Thank you! You were really helpful. It worked!
Hi, community!
I am trying to find a motif in a DNA sequence. This is my code:
#!/usr/bin/env python3
from sys import argv
import re
#Functions
def find_motif(seq_dna, motif):
results = re.finditer(motif, seq_dna)
r = []
for result in results:
r.append(result.span()[0] + 1)
print(" ".join(map(str, r)))
if __name__=='__main__':
seq_dna = argv[1]
motif = argv[2]
find_motif(seq_dna, motif)
By running my code as python finding_motif.py "GATATATGCATATACTT" "ATAT", this is the stdout:
2 10
However, there is another motif in index 3 that is not counted. Could somebody help me with a way how to tackle this? The real output is:
2 4 10
Thank you for your help in advance
3 answers
I dont know why your code doesn't work, maybe it is because "re" restarts looking after the index of the first match. Here is my solution:
s = "GATATATGCATATACTT"
for i in range(len(s)):
if s[i:].startswith("ATAT"):
print(i+1)
It says on re library documentation page:
re.finditer(pattern, string, flags=0)
Return an iterator yielding match objects over all non-overlapping matches for the RE pattern in string. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result.
Your matches are overlapping, so it will find only the first of them. You should be able to solve this by looping through the string using re.search, which is described on the same page, or using re.findall as described here.
Thank you so much for your help; however, I could not understand what flags meant, but I don't know if changing it to another number it's possible to assign overlapped matches? I could not find that information in the documentation page.
Here is an explanation of those flags.
There is no flag for overlapping matches.
But the flags re.MULTILINE and re.IGNORECASE could be useful in another context.
Thank you so much, It was really helpful.
Another option is to use the third party regex module, which is a drop-in replacement for re but supports overlapping matches natively IIRC.
This is only a minor modification of your code using the lookahead from this answer.
import re
OFFSET = 1
def find_motif(seq_dna, motif):
return list((m.start() + OFFSET) for m in re.finditer("(?=" + motif + ")", seq_dna))
print(find_motif("GATATATGCATATACTT", "ATAT"))
Prints: [2, 4, 10]
start() and ?= were new to me. Great comment! Thank you
Log in to answer this question.
btw., you can do
print(*r)instead of the print-join-map business, which is equivalent toprint(r[0], r[1],etc.).Wow! I did not know about that. Thank you!! It worked.