如何防止我的列表理解引发停止迭代

2024-04-26 12:32:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在浏览一个有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样式的列表理解,但是我可以构建一个样式类似于:

^{pr2}$

衷心感谢你的帮助。在


Tags: 代码in列表forif记录样式content
2条回答

您可以使用itertools获取一个切片。some_list的长度为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模块中的recipe

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)

例如

^{pr2}$

所以你可以这么做

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来知道您是谁,例如

lines = content.split("\n")
iterator = iter(enumerate(lines))
for i,line in iterator:
    ...
    if not isRecord(keyword) :
        consume(iterator,2)

相关问题 更多 >