为什么我的 for 循环 (python) 在 4 次迭代后会改变行为?
Why does my for loop (python) shift behaviour after 4 iterations?
我正在尝试编写一个程序来移动 DNA 序列的定义长度的元素,但我无法理解我从循环中获得的输出。对于循环的前四次迭代,它似乎可以很好地移码,然后似乎恢复到旧序列。我已经非常努力地理解这种行为,但我对编程还太陌生,无法解决这个问题,非常感谢任何帮助。
这是我的代码:
seq = "ACTGCATTTTGCATTTT"
search = "TGCATTTTG"
import regex as re
def kmers(text,n):
for a in text:
b = text[text.index(a):text.index(a)+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
(kmers(seq,3))
我的输出:
the count for ACT is 1
the count for CTG is 1
the count for TGC is 2
the count for GCA is 2
#I expected 'CAT' next, from here on I don't understand the behaviour
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for GCA is 2
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
显然,最终我想删除重复项等,但由于我的 for 循环无法按我预期的方式工作而陷入困境,这让我无法继续改进。
谢谢
text.index
总是 returns 找到第一个索引。由于您逐个字母地迭代 seq
,因此当您第一次点击之前找到的字母时,您会得到奇怪的结果。
第 5 个字母是第一个重复项,c
,因此 text.index('c')
返回第一个 c
的索引,1 而不是您期望的 4 - 并且您复制了上次点击 c
.
此方法效率低下 - 您似乎对在索引之间移动比在字母之间移动更感兴趣,所以我会使用:
for a in range(len(text)-(n-1)):
b = text[a:a+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
而不是每次都搜索索引,这既低效又会产生错误的结果。 findall
在这里也是一种低效的计数方式 - 可以构建字典,特别是 defaultdict
以更有效地计数。
请注意,您可以使用一些不错的内置函数:
>>> from collections import Counter
>>> seq='ACTGCATTTTGCATTTT'
>>> Counter((seq[i:i+3] for i in range(len(seq)-2)))
Counter({'TTT': 4, 'TGC': 2, 'GCA': 2, 'CAT': 2, 'ATT': 2, 'ACT': 1, 'CTG': 1, 'TTG': 1})
最后的命中是字符串结束的地方,你可以忽略它们。
我正在尝试编写一个程序来移动 DNA 序列的定义长度的元素,但我无法理解我从循环中获得的输出。对于循环的前四次迭代,它似乎可以很好地移码,然后似乎恢复到旧序列。我已经非常努力地理解这种行为,但我对编程还太陌生,无法解决这个问题,非常感谢任何帮助。
这是我的代码:
seq = "ACTGCATTTTGCATTTT"
search = "TGCATTTTG"
import regex as re
def kmers(text,n):
for a in text:
b = text[text.index(a):text.index(a)+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
(kmers(seq,3))
我的输出:
the count for ACT is 1
the count for CTG is 1
the count for TGC is 2
the count for GCA is 2
#I expected 'CAT' next, from here on I don't understand the behaviour
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for GCA is 2
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
显然,最终我想删除重复项等,但由于我的 for 循环无法按我预期的方式工作而陷入困境,这让我无法继续改进。
谢谢
text.index
总是 returns 找到第一个索引。由于您逐个字母地迭代 seq
,因此当您第一次点击之前找到的字母时,您会得到奇怪的结果。
第 5 个字母是第一个重复项,c
,因此 text.index('c')
返回第一个 c
的索引,1 而不是您期望的 4 - 并且您复制了上次点击 c
.
此方法效率低下 - 您似乎对在索引之间移动比在字母之间移动更感兴趣,所以我会使用:
for a in range(len(text)-(n-1)):
b = text[a:a+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
而不是每次都搜索索引,这既低效又会产生错误的结果。 findall
在这里也是一种低效的计数方式 - 可以构建字典,特别是 defaultdict
以更有效地计数。
请注意,您可以使用一些不错的内置函数:
>>> from collections import Counter
>>> seq='ACTGCATTTTGCATTTT'
>>> Counter((seq[i:i+3] for i in range(len(seq)-2)))
Counter({'TTT': 4, 'TGC': 2, 'GCA': 2, 'CAT': 2, 'ATT': 2, 'ACT': 1, 'CTG': 1, 'TTG': 1})
最后的命中是字符串结束的地方,你可以忽略它们。