代码之家  ›  专栏  ›  技术社区  ›  Mike

Python for loop展望未来

  •  13
  • Mike  · 技术社区  · 14 年前

    我有一个python for循环,在这个循环中,我需要查看一个项目,看看是否需要在处理之前执行一个操作。

    for line in file:
        if the start of the next line == "0":
            perform pre-processing
            ...
        continue with normal processing
        ...
    

    在python中有什么简单的方法可以做到这一点吗? 我目前的方法是将文件缓冲到一个数组中,但是这并不理想,因为文件很大。

    7 回复  |  直到 14 年前
        1
  •  18
  •   nosklo    14 年前

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

    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)
    

    示例用法:

    for line, next_line in get_next(myfile):
        if next_line and next_line.startswith("0"):
            ... do stuff
    

    代码允许您通过 window 如果要向前看2行或更多行,请将参数设置为更大的值。

        2
  •  9
  •   icyrock.com    14 年前

    你可以有一个 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
    

    如果需要,您可能需要对最后一行进行额外的处理,这取决于您的逻辑。

        3
  •  8
  •   Muhammad Alkarouri    14 年前

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

    功能 pairwise 从优秀的 itertools recipes 非常适合:

    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)
    

    在代码中使用它可以让我们:

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

    通常,对于这种类型的处理(iterable中的lookahead),我倾向于使用 window function . 两厢是2号窗户的特例。

        4
  •  3
  •   unholysampler    14 年前

    你只需要缓冲一行。

    for line in file:
      if (prevLine is not None):
        //test line as look ahead and then act on prevLine
      prevLine = line
    
        5
  •  2
  •   Jochen Ritzel    14 年前

    这也应该管用。我总是喜欢打电话 next 过度设置 something = None 第一轮。

    prev_line = next(the_file)
    for current_line in the_file:
        if current_line.startswith('0'):
            do_stuff( prev_line )
        # continue with normal processing
        # ...
        prev_line = current_line
    
        6
  •  1
  •   pylang    7 年前

    more_itertools 有几个 lookahead tools . 在这里,我们将演示一些工具和处理文件行的抽象函数。鉴于:

    f = """\
    A
    B
    C
    0
    D\
    """
    lines = f.splitlines()
    

    代码

    import more_itertools as mit
    
    
    def iter_lookahead(iterable, pred):
        # Option 1
        p = mit.peekable(iterable)
        try:
            while True:
                line = next(p)
                next_line = p.peek()
                if pred(next_line):
                    # Do something
                    pass
                else:
                    print(line)
        except StopIteration:
            return
    
    
    pred = lambda x: x.startswith("0")
    iter_lookahead(lines, pred)
    

    输出

    A
    B
    0
    

    以下是使用同一个库的其他选项,包括 pairwise windowed @Muhammad Alkarouri提到的工具。

    # Option 2
    for line, next_line in mit.pairwise(lines):
        if pred(next_line):            
            # Do something
            pass
        else:
            print(line)
    
    # Option 3
    for line, next_line in mit.windowed(lines, 2):
        if pred(next_line):            
            # Do something
            pass
        else:
            print(line)
    

    后一个选项可以独立运行或替换先前函数中的逻辑。

        7
  •  -3
  •   Stephen    14 年前

    我不是Python专家,但我想您需要为此使用两个循环。for循环的第一次运行应该构建一个索引列表,需要对其执行特殊操作。然后在第二次运行时,可以将当前索引与列表进行比较,以确定是否需要执行该特殊操作。