Python 如何防止列表理解引发stopIteration错误

Python 如何防止列表理解引发stopIteration错误,python,for-loop,list-comprehension,stopiteration,Python,For Loop,List Comprehension,Stopiteration,我正在浏览一个包含3行记录的文本文件。如果在第一行,我可以说这是一个我不想计数的记录,我想移到下一个记录的开始,再往下2行。目前,我运行的代码片段如下: lines = content.split("\n") iterable = iter(xrange(len(lines))) for i in iterable: line = lines[i] ... if isRecord(keyword) == False: [iterable.next() for x

我正在浏览一个包含3行记录的文本文件。如果在第一行,我可以说这是一个我不想计数的记录,我想移到下一个记录的开始,再往下2行。目前,我运行的代码片段如下:

lines = content.split("\n")
iterable = iter(xrange(len(lines)))
for i in iterable:
    line = lines[i]
...
    if isRecord(keyword) == False:
        [iterable.next() for x in range(2)]
在文件的最后,我的理解可能会抛出一个stopIteration错误。我如何添加到代码中,以便如果我提出stopIteration,它将打破for循环?我已经研究了列表理解中的许多条目,以及如何基于stopIteration标志构建for循环以停止,但我还不知道如何将其应用到我自己的代码中。我也见过使用if/else/for样式的列表理解,但是我可以构建一个具有如下样式的列表:

[iterable.next() for x in range(2) else break]

衷心感谢您的帮助。

您可以使用itertools切一片。一些_列表的长度为2、1或0,具体取决于列表剩余的长度。如果列表较大,将从迭代器中删除2项,for循环将继续执行下一项

import itertools

lines = content.split("\n")
iterable = iter(xrange(len(lines)))
for i in iterable:
    line = lines[i]
...
    if isRecord(keyword) == False:
        some_list = list(itertools.islice(iterable, 2))

您还可以以这样的方式构造iterable,即一次获得3个项,例如,使用itertools模块中的这一项

from itertools import izip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)
比如说

>>> for x in grouper(xrange(10),3):
        print x


(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9, None, None)
>>> 
lines = content.split("\n")
iterator = iter(enumerate(lines))
for i,line in iterator:
    ...
    if not isRecord(keyword) :
        consume(iterator,2)
所以对于你的情况,你可以这样做

lines = content.split("\n")
for line,x,y in grouper(lines,3):
    ...
    if not isRecord(keyword) :
        continue # go to the next iteration
或者,如果内容不是纯3行块中的格式,则消费配方

from itertools import islice
import collections 

def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)
范例

>>> it=iter(xrange(10))
>>> consume(it,5)
>>> list(it)
[5, 6, 7, 8, 9]
>>> 
如果您真的需要,您还可以使用enumerate来了解您是谁,例如

>>> for x in grouper(xrange(10),3):
        print x


(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9, None, None)
>>> 
lines = content.split("\n")
iterator = iter(enumerate(lines))
for i,line in iterator:
    ...
    if not isRecord(keyword) :
        consume(iterator,2)

假设在点击下一个按钮时,剩余1或0项。这应该创建长度为1或0的列表,还是应该是某种错误?好问题!这应该打破记录处理,开始处理不同的文件。在推进列表之前,有没有一种方法可以告诉我列表中还有多少元素?嘿,这太棒了!我将尝试一下,看看它是如何工作的!非常感谢。名单!这就是我所缺少的——我尝试了一些列表中的len、str和int,感觉我真的需要花一些时间来处理这个!最终,我在咀嚼之前使用了一个正则表达式替换来删除非标准长度。谢谢你们两位!哦,我也喜欢这个!这个概念我非常熟悉,所以我认为在未来的迭代中,我将使用这个实现。非常感谢。