Python for-loop超前

Mik*_*ike 13 python

我有一个Python for循环中,我需要向前看一个项目,看是否需要采取行动处理之前进行.

for line in file:
    if the start of the next line == "0":
        perform pre-processing
        ...
    continue with normal processing
    ...
Run Code Online (Sandbox Code Playgroud)

有没有简单的方法在python中执行此操作?我目前的方法是将文件缓冲到一个数组,但这并不理想,因为文件相当大.

nos*_*klo 17

您可以使用此配方获取任何可迭代的预取下一个项目:

from itertools import tee, islice, izip_longest
def get_next(some_iterable, window=1):
    items, nexts = tee(some_iterable, 2)
    nexts = islice(nexts, window, None)
    return izip_longest(items, nexts)
Run Code Online (Sandbox Code Playgroud)

用法示例:

for line, next_line in get_next(myfile):
    if next_line and next_line.startswith("0"):
        ... do stuff
Run Code Online (Sandbox Code Playgroud)

window如果您想要查看2行或更多行,则代码允许您将参数作为较大的值传递.

  • 你的`get_next`在[`pairwise`]中的itertools receipes中(http://docs.python.org/library/itertools.html#recipes) (4认同)
  • 它只读一次.参见[`itertoolsmodule.c`]中的`teedataobject_getitem`(http://svn.python.org/projects/python/branches/release27-maint/Modules/itertoolsmodule.c) (3认同)
  • @nosklo:这不是我的方法.正如THC4k所说,它是来自itertools帮助的`pairwise`函数.`islice`唯一的问题是对此有点矫枉过正.`izip_longest`和`izip`是不同的,当你需要最后一对有'None'时,你使用最长的变化,这与你正在检查排除'None`时所做的完全相反.我的主要答案是提请注意itertools食谱.但是,如果你认为这是一个争论做任何你喜欢的问题.我可能最好挂到我的20分,而不是删除几乎重复的答案. (2认同)

icy*_*com 9

您可以拥有prev_line存储前一行的位置,并在您根据条件阅读行时进行处理.

就像是:

prev_line = None
for line in file:
    if prev_line is not None and the start of the next line == "0":
        perform pre-processing on prev_line
        ...
    continue with normal processing
    ...
    prev_line = line
Run Code Online (Sandbox Code Playgroud)

如有必要,您可能需要对最后一行进行其他处理,具体取决于您的逻辑.


Muh*_*uri 8

按照nosklo的回答,我倾向于使用以下模式:

该功能pairwise从优秀itertools食谱是非常理想的:

from itertools import tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)
Run Code Online (Sandbox Code Playgroud)

在代码中使用它可以获得:

for line, next_line in pairwise(file):
    if next_line.startswith("0"):
        pass #perform pre-processing
        #...
    pass #continue with normal processing
Run Code Online (Sandbox Code Playgroud)

通常,对于这种类型的处理(可迭代中的前瞻),我倾向于使用窗口函数.Pairwise是一个大小为2的窗口的特例.

  • @nosklo:试一试.我相信你能比我的链接更好,因为我只是在解释这个概念.我也可以做得更好.请注意,它并不像您想象的那么简单.我不知道我做了什么来打扰你,但我希望我们可以得到最好的答案.如果你编辑你的到达那里,我会非常高兴. (2认同)