过去几天我一直在努力解决特定的生物信息学问题,我想知道是否有人能够在我的逻辑中找到错误或在我的代码中找到错误(或两者都有)。 该函数应该从所有DNA串中找到所有k-mers,其汉明距离最多为d。 这就是我想要做的事情:
从所有可能的k-mers的迭代开始,并将它们与每个字符串进行比较
这意味着我需要另一个遍历DNA串的循环
我为c+k <= len(DNA[0])-1
制作了一个while循环。 c+k
是我的大小为k
的窗口,我想在每个DNA字符串中找到至少一个窗口,其中我的组合与该字符串的汉明距离等于或小于任意{{1 }}。如果汉明距离符合标准,则while循环中断,允许比较下一个字符串。如果没有,则窗口会发生变化,如果d
,汉明距离仍然不符合标准,我会创建一个名称错误c+k==len(DNA[0])-1
,异常会导致{{1} }}
但是,我的函数只返回int(a)
以外的任何内容,我不明白。
inner_loop
我认为自从我的第二个内循环崩溃后,这将导致我的第一个内循环通过,然后set()
中的另一个组合将被测试,但我的import itertools
def combination(k):
bases=['A','T','G','C']
combo=[''.join(p) for p in itertools.product(bases, repeat=k)]
return combo
def hammingDistance(Pattern, seq):
if Pattern == seq:
return 0
else:
dist=0
for i in range(len(seq)):
if Pattern[i] != seq[i]:
dist += 1
return dist
def motif_enumeration(k, d, DNA):
combos = combination(k)
global pattern
for combo in combos:
try:
inner_loop(k, d, DNA, combo)
except:
continue
return set(pattern)
def inner_loop(k, d, DNA, combo):
global pattern
for strings in DNA:
inner_loop_two(k, d, DNA, combo, strings)
def inner_loop_two(k, d, DNA, combo, strings):
global pattern
c=0
while c+k < len(DNA[0]):
print(combo, strings[c:c+k], hammingDistance(combo, strings[c:c+k]))
if d >= hammingDistance(combo, strings[c:c+k]) and strings == DNA[len(DNA)-1]:
#if we've reached the last string and the condition is met,
#that means that the combo is suitable for each string of DNA
pattern += [combo]
elif d >= hammingDistance(combo, strings[c:c+k]):
#condition is met for one string, now move onto next
break
elif d < hammingDistance(combo, strings[c:c+k]) and c+k == len(DNA[0])-1:
#Name error causes this inner loop two to crash, thus causing the first inner loop
#to pass
int(a)
elif d < hammingDistance(combo, strings[c:c+k]):
#change the window to see if the combo is valid later in the string
c += 1
pattern = []
DNA=['ATTTGGC', 'TGCCTTA', 'CGGTATC', 'GAAAATT']
print(motif_enumeration(3,1,DNA))
print(pattern)
中的第一个条件永远不会打印任何东西。我还注意到,当内循环崩溃并且motif_enumeration
继续时,它继续用于外循环和内循环。这是我的意思的一个例子......
inner_loop_two
我的预期输出为motif_enumeration
答案 0 :(得分:2)
逻辑的核心组件是,如果组合在目标字符串的所有上的任何位置匹配,我们希望将组合收集到模式集中。我们可以使用Python的all
和any
函数来执行此操作。这些功能可以有效地工作,因为它们会在决定结果后立即停止测试。
import itertools
def combination(k):
return (''.join(p) for p in itertools.product('ATCG', repeat=k))
def hamming_distance(pattern, seq):
return sum(c1 != c2 for c1, c2 in zip(pattern, seq))
def window(s, k):
for i in range(1 + len(s) - k):
yield s[i:i+k]
def motif_enumeration(k, d, DNA):
pattern = set()
for combo in combination(k):
if all(any(hamming_distance(combo, pat) <= d
for pat in window(string, k)) for string in DNA):
pattern.add(combo)
return pattern
DNA = ['ATTTGGC', 'TGCCTTA', 'CGGTATC', 'GAAAATT']
print(motif_enumeration(3, 1, DNA))
<强>输出强>
{'GTT', 'ATA', 'TTT', 'ATT'}
我对您的代码进行了一些其他更改。我们可以通过将生成器传递给sum
函数来有效地计算汉明距离。我们可以节省时间和时间RAM通过使用生成器将组合元组转换为字符串而不是将它们放入列表中。
motif_enumeration
函数可以进一步浓缩为集合理解,但我必须承认它相当密集,甚至比以前的版本更难阅读。但是,它可能稍微有点效率。
def motif_enumeration(k, d, DNA):
return {combo for combo in combination(k)
if all(any(hamming_distance(combo, pat) <= d
for pat in window(string, k)) for string in DNA)}
这是一个稍微易读的版本,我已经给motif_enumeration
辅助函数in_window
执行内部测试。
# Return True if combo is within d in any window of string
def in_window(combo, string, k, d):
return any(hamming_distance(combo, pat) <= d for pat in window(string, k))
def motif_enumeration(k, d, DNA):
pattern = set()
for combo in combination(k):
if all(in_window(combo, string, k, d) for string in DNA):
pattern.add(combo)
return pattern