我编写了以下代码,在文本文件中定义4行块,如果块的第2行仅由一种类型的字符组成,则输出该块。假设(和先前验证)第2行总是由一个由36个字符组成的字符串。
# filter out homogeneous reads
import sys
import collections
from collections import Counter
filename1 = sys.argv[1] # file to process
with open(filename1,'r') as input_file:
for line1 in input_file:
line2, line3, line4 = [next(input_file) for line in xrange(3)]
c = Counter(line2).values() # count characters in line2
c.sort(reverse=True) # sort values in descending order
if c[0] < 36:
print line1 + line2 + line3 + line4.rstrip()但是,我得到一个StopIteration错误如下所示。如果有人能告诉我原因,我会很感激的。
$ python code.py test.file > testout.file
Traceback (most recent call last):
File "code.py", line 11, in <module>
line2, line3, line4 = [next(input_file) for line in xrange(3)]
StopIteration任何帮助都将不胜感激,尤其是解释我的特定代码有什么问题以及如何修复它的那种帮助。下面是一个输入示例:
@1:1:1323:1032:Y
AGCAGCATTGTACAGGGCTATCATGGAATTCTCGGG
+1:1:1323:1032:Y
HHHBHHBHBHGBGGGH8HHHGGGGFHBHHHHBHHHH
@1:1:1610:1033:Y
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+1:1:1610:1033:Y
HHEHHHHHHHHHHHBGGD>GGD@G8GGGGDHBHH4C
@1:1:1679:1032:Y
CGGTGGATCACTCGGCTCGTGCGTCGATGAAGAACG发布于 2015-12-23 11:13:47
您的示例输入已经显示了问题:您有10行代码,这在4之前是不可分割的。因此,当您阅读最后一个块时,您得到了line1和line2,但是对于对line3的next()调用,输入已经耗尽,您什么也得不到。
很可能在完整的输入文件中也存在相同的问题:行数不能被4整除。
有几种方法可以克服这一点。最好的方法可能是修复您的输入,因为您似乎一直在期待四行代码,如果输入文件给出的不是这样的话,就会出现内容问题。
另一个非常简单的修复方法是使用next()指定默认值。
line2, line3, line4 = [next(input_file, '') for line in xrange(3)]现在,当next()失败时,将返回默认值''。因此,即使文件已经耗尽,您仍然可以获得一些内容。
不过,一个可能更好的解决方案是修复迭代文件的方式。您有两个位置访问相同的文件迭代器,一次在外部for循环中,三次在列表理解中。这看起来很简单,所以您不会遇到其他问题,但您确实应该尝试改变这种情况,这样您就只能在一个位置上遍历迭代器;或者只使用next()调用,但是将其与for循环混合似乎是个坏主意。
例如,您可以使用grouper recipe以四个组的形式干净地迭代文件:
with open(filename1, 'r') as input_file:
for line1, line2, line3, line4 in grouper(input_file, 4, fillvalue=''):
# do things with the lines发布于 2015-12-23 11:13:01
如果文件中的行数不能除以没有余数的4,您将得到这个结果。然后,您将尝试读取不存在的行。你需要数空行。
一种解决方案是,如果行数不足以处理文件,则停止处理:
try:
line2, line3, line4 = [next(input_file) for line in xrange(3)]
except StopIteration:
break这感觉有点干净:
while True:
try:
line1, line2, line3, line4 = [next(input_file) for line in xrange(4)]
except StopIteration:
break因为迭代器只能在一个地方进行,而不是在两个地方。
发布于 2015-12-23 11:22:34
您有10行,因此它可以迭代2时间,然后就会出现2行短缺问题。这就是Python无法读取足够多的行并抛出StopIteration的地方。
看看这段代码,我稍微更新了一下:
import sys
import collections
from collections import Counter
filename1 = sys.argv[1] # file to process
with open(filename1,'r') as input_file:
while True:
try:
line1, line2, line3, line4 = [next(input_file) for line in xrange(4)]
except StopIteration:
print "Not enough lines to read!"
break
c = Counter(line2).values() # count characters in line2
c.sort(reverse=True) # sort values in descending order
if c[0] < 36:
print line1 + line2 + line3 + line4.rstrip()
else:
print "Skipping 4 lines since less than 36 characters"https://stackoverflow.com/questions/34434135
复制相似问题