不知道为什么我会收到 StopIteration 错误
Don't know why I am getting StopIteration error
我正在编写一个从文件接收输入的程序,每行可能包含 "ATG" 或 "GTG",我很确定我所做的一切都是正确的去做。这是我第一次在 python 中使用生成器,在研究了这个问题之后,我仍然不知道为什么我会停止迭代。为此,我的生成器必须生成一个元组,其中包含在每个字符串中找到的 ATG 或 GTG 的起始位置。
import sys
import p3mod
gen = p3mod.find_start_positions()
gen.send(None) # prime the generator
with open(sys.argv[1]) as f:
for line in f:
(seqid,seq) = line.strip().lower().split()
slocs = gen.send(seq)
print(seqid,slocs,"\n")
gen.close() ## added to be more official
这是生成器
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
retVal = ()
x = 0
loc = -1
locations = []
while (x + 3) < len(DNAstr):
if (DNAst[x:x+3] is "ATG" or DNAstr[x:x+3] is "GTG" ):
loc = x
if loc is not -1:
locations.append(loc)
loc = -1
yield (tuple(locations))
这是错误:
Traceback (most recent call last):
File "p3rmb.py", line 12, in <module>
slocs = gen.send(seq)
StopIteration
您制作了一个 returns 一次性生成所有数据的生成器。
您应该在每次迭代中产生数据。此代码可能并不完美,但它可能会解决您的部分问题:
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
x = 0
loc = -1
while x + 3 < len(DNAstr):
if DNAst[x:x+3] == "ATG" or DNAstr[x:x+3] == "GTG" :
loc = x
if loc is not -1:
yield loc
loc = -1
StopIteration 不是错误。这是生成器发出信号表明它耗尽了所有数据的方式。您只需要 "try except" 它或在已经为您完成的 forloop 中使用您的生成器。
尽管它们并不那么复杂,但可能需要一些时间来适应这些 "weird" 错误。 ;)
您的生成器在其整个生命周期中 return 只有一个值。它遍历 while
循环,一举找到整个列表中的所有 locations
和 return。因此,当您第二次调用 send
时,您已经耗尽了生成器的操作。
您需要弄清楚您对每次调用 send
的期望;配置你的循环以产生那么多,然后 yield
结果......并为将来的 send
调用继续这样做。您的 yield
语句必须在循环内才能正常工作。
Jayme 在他的回答中给了你一个很好的例子。
有一个内置的 find() 函数可以在给定的字符串中查找子字符串。这里真的需要发电机吗?
相反,您可以尝试:
import sys
with open(sys.argv[1]) as f:
text = f.read()
for i, my_string in enumerate(text.strip().lower().split()):
atg_index = my_string.find('atg')
gtg_index = my_string.find('gtg')
print(i, atg_index, gtg_index, my_string)
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
x = 0
loc = -1
while x + 3 < len(DNAstr):
if DNAst[x:x+3] == "ATG" or DNAstr[x:x+3] == "GTG" :
loc = x
if loc is not -1:
yield loc
loc = -1
我正在编写一个从文件接收输入的程序,每行可能包含 "ATG" 或 "GTG",我很确定我所做的一切都是正确的去做。这是我第一次在 python 中使用生成器,在研究了这个问题之后,我仍然不知道为什么我会停止迭代。为此,我的生成器必须生成一个元组,其中包含在每个字符串中找到的 ATG 或 GTG 的起始位置。
import sys
import p3mod
gen = p3mod.find_start_positions()
gen.send(None) # prime the generator
with open(sys.argv[1]) as f:
for line in f:
(seqid,seq) = line.strip().lower().split()
slocs = gen.send(seq)
print(seqid,slocs,"\n")
gen.close() ## added to be more official
这是生成器
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
retVal = ()
x = 0
loc = -1
locations = []
while (x + 3) < len(DNAstr):
if (DNAst[x:x+3] is "ATG" or DNAstr[x:x+3] is "GTG" ):
loc = x
if loc is not -1:
locations.append(loc)
loc = -1
yield (tuple(locations))
这是错误:
Traceback (most recent call last):
File "p3rmb.py", line 12, in <module>
slocs = gen.send(seq)
StopIteration
您制作了一个 returns 一次性生成所有数据的生成器。 您应该在每次迭代中产生数据。此代码可能并不完美,但它可能会解决您的部分问题:
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
x = 0
loc = -1
while x + 3 < len(DNAstr):
if DNAst[x:x+3] == "ATG" or DNAstr[x:x+3] == "GTG" :
loc = x
if loc is not -1:
yield loc
loc = -1
StopIteration 不是错误。这是生成器发出信号表明它耗尽了所有数据的方式。您只需要 "try except" 它或在已经为您完成的 forloop 中使用您的生成器。 尽管它们并不那么复杂,但可能需要一些时间来适应这些 "weird" 错误。 ;)
您的生成器在其整个生命周期中 return 只有一个值。它遍历 while
循环,一举找到整个列表中的所有 locations
和 return。因此,当您第二次调用 send
时,您已经耗尽了生成器的操作。
您需要弄清楚您对每次调用 send
的期望;配置你的循环以产生那么多,然后 yield
结果......并为将来的 send
调用继续这样做。您的 yield
语句必须在循环内才能正常工作。
Jayme 在他的回答中给了你一个很好的例子。
有一个内置的 find() 函数可以在给定的字符串中查找子字符串。这里真的需要发电机吗?
相反,您可以尝试:
import sys
with open(sys.argv[1]) as f:
text = f.read()
for i, my_string in enumerate(text.strip().lower().split()):
atg_index = my_string.find('atg')
gtg_index = my_string.find('gtg')
print(i, atg_index, gtg_index, my_string)
def find_start_positions (DNAstr = ""):
DNAstr = DNAstr.upper()
x = 0
loc = -1
while x + 3 < len(DNAstr):
if DNAst[x:x+3] == "ATG" or DNAstr[x:x+3] == "GTG" :
loc = x
if loc is not -1:
yield loc
loc = -1