从文件中读取行作为移位寄存器,在Python中使用两个单元格

时间:2014-05-23 07:22:08

标签: python

我需要以这样的方式读取文件的行,它将作为具有两个单元的移位寄存器。 例如:

with open("filename", 'r') as file:

 --first iteration--
 present = line1
 next  = line2
    do something

 --second iteration--
 present = line2
 next = line3
   do something

 --third iteration--
 present = line3
 next = line 4
    do someting

 and so on....

可以使用open(file, 'r')完成,但不保证文件将在脚本停止时关闭 由于在最后一次迭代之前“做某事”。

任何优雅的方式吗?

3 个答案:

答案 0 :(得分:7)

不确定

with open("filename", 'r') as file:
    current_line = next(file)  # Get 1st line, advance iterator to 2nd line
    for next_line in file:
        do_something(current_line, next_line)
        current_line = next_line

答案 1 :(得分:5)

蒂姆的答案很好。 A"鸽友"解决方案是使用itertoos docs中显示的pairwise来使用itertools.tee食谱:

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return zip(a, b)

tee是一个非常简洁的功能。它可以在您想要多次迭代同一个迭代时使用。如果您或多或少地并行使用所有迭代器(而不是运行一次迭代完成,然后执行下一次迭代等),那么将整个迭代转储到{{1或者其他一些可以反复迭代的容器。

基本上,你传递一个可迭代对象,它返回一些独立的迭代器(默认情况下,两个)。原始的iterable仅在处理返回迭代器之前最远的位置时才会提前。

这是一个带有生成器的list演示,它在产生值之前打印一条消息:

tee

答案 2 :(得分:2)

Tim's answerBlckknght's answer很好。要添加到解决方案池,您还可以使用deque:

执行此操作
from collections import deque
n = 2
with open('myfile', 'r') as infile:
    window = deque(maxlen=n)
    for line in infile:
        window.append(line)
        do_something(*window)

更一般地说,您可以创建一个从双端队列产生的生成器:

def sliding_window(iterable, n=2, fill_value=None, add_padding=False):
    it = iter(iterable)
    if add_padding:
        window = deque([fill_value for _ in range(n-1)], maxlen=n)
        window.append(next(it))
    else:
        window = deque([next(iterable) for _ in range(n)], maxlen=n)

    yield tuple(window)

    for item in it:
        window.append(it)
        yield tuple(window)

    if add_padding:
        for _ in range(n-1):
            window.append(fill_value)
            yield tuple(window)

请注意,如果iterable中的值少于n,则上述实施将产生空生成器。