首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >定义xrange后的StopIteration

定义xrange后的StopIteration
EN

Stack Overflow用户
提问于 2015-12-23 10:57:57
回答 3查看 203关注 0票数 1

我编写了以下代码,在文本文件中定义4行块,如果块的第2行仅由一种类型的字符组成,则输出该块。假设(和先前验证)第2行总是由一个由36个字符组成的字符串。

代码语言:javascript
复制
# 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错误如下所示。如果有人能告诉我原因,我会很感激的。

代码语言:javascript
复制
$ 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

任何帮助都将不胜感激,尤其是解释我的特定代码有什么问题以及如何修复它的那种帮助。下面是一个输入示例:

代码语言:javascript
复制
@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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-23 11:13:47

您的示例输入已经显示了问题:您有10行代码,这在4之前是不可分割的。因此,当您阅读最后一个块时,您得到了line1line2,但是对于对line3next()调用,输入已经耗尽,您什么也得不到。

很可能在完整的输入文件中也存在相同的问题:行数不能被4整除。

有几种方法可以克服这一点。最好的方法可能是修复您的输入,因为您似乎一直在期待四行代码,如果输入文件给出的不是这样的话,就会出现内容问题。

另一个非常简单的修复方法是使用next()指定默认值。

代码语言:javascript
复制
line2, line3, line4 = [next(input_file, '') for line in xrange(3)]

现在,当next()失败时,将返回默认值''。因此,即使文件已经耗尽,您仍然可以获得一些内容。

不过,一个可能更好的解决方案是修复迭代文件的方式。您有两个位置访问相同的文件迭代器,一次在外部for循环中,三次在列表理解中。这看起来很简单,所以您不会遇到其他问题,但您确实应该尝试改变这种情况,这样您就只能在一个位置上遍历迭代器;或者只使用next()调用,但是将其与for循环混合似乎是个坏主意。

例如,您可以使用grouper recipe以四个组的形式干净地迭代文件:

代码语言:javascript
复制
with open(filename1, 'r') as input_file:
    for line1, line2, line3, line4 in grouper(input_file, 4, fillvalue=''):
        # do things with the lines
票数 2
EN

Stack Overflow用户

发布于 2015-12-23 11:13:01

如果文件中的行数不能除以没有余数的4,您将得到这个结果。然后,您将尝试读取不存在的行。你需要数空行。

一种解决方案是,如果行数不足以处理文件,则停止处理:

代码语言:javascript
复制
try:
    line2, line3, line4 = [next(input_file) for line in xrange(3)]
except StopIteration:
    break

这感觉有点干净:

代码语言:javascript
复制
while True:
    try:
        line1, line2, line3, line4 = [next(input_file) for line in xrange(4)]
except StopIteration:
    break

因为迭代器只能在一个地方进行,而不是在两个地方。

票数 1
EN

Stack Overflow用户

发布于 2015-12-23 11:22:34

您有10行,因此它可以迭代2时间,然后就会出现2行短缺问题。这就是Python无法读取足够多的行并抛出StopIteration的地方。

看看这段代码,我稍微更新了一下:

代码语言:javascript
复制
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"
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34434135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档