繁体   English   中英

防止 itertools.islice 修改行

[英]prevent itertools.islice from modifying lines

当逐行读取文件时,如果找到一个字符串,它将在之前和之后打印多行。 但是,当我抓住这些线条之后,它会删除它们。 我该怎么做才能使读取的行不受影响

data.txt
----------------------------
apple
banana
carrot
dog
egg
food
george
hat
ink
jacket
kiwi
lemon
mango

import itertools
import collections

with open("text", "r") as f:
    linesBefore = collections.deque(maxlen=4)
    for line in f:
        line.rstrip()
        if "george" in line:
            history = list(map(str.strip, linesBefore))
            history.append(line.rstrip())
            append = list(itertools.islice(f, 4))
            append = list(map(str.strip, append))
        linesBefore.append(line)
        print(line.rstrip())
#print('\n'.join(history))
#print('\n'.join(append))

正如您在打印行时所看到的,您可以看到在字符串“george”之后抓取的文本不在 output 中

apple
banana
carrot
dog
egg
food
george
lemon
mango

这些行不在 output 中,因为您从未打印过它们。 您的if "george"子句将它们从文件迭代器中删除并将它们放入linesBefore中。 如果您希望它们出现在 output 中,则必须明确地将它们放在那里。

我在您的条款中添加了一个简单的行:

    if "george" in line:
        history = list(map(str.strip, linesBefore))
        history.append(line.rstrip())
        append = list(itertools.islice(f, 4))
        append = list(map(str.strip, append))
        print(append)

然后是 output

apple
banana
carrot
dog
egg
food
['hat', 'ink', 'jacket', 'kiwi']
george
lemon
mango

有缺失的单词,就在你离开它们的地方。

您可以通过在看到目标行时保存和恢复文件的当前 position 来做到这一点 - 但是您不能使用next()遍历文件(直接或间接通过for line in file:itertools.islice() ) 使用seek()时,因此您必须以不同的方式阅读这些行。 这实际上很简单:

import collections

with open("data_text.txt", "r") as f:
    linesBefore = collections.deque(maxlen=4)

    while True:
        line = f.readline().rstrip()
        if not line:
            break

        if "george" in line:
            posn = f.tell()  # Save where next line starts.
            history = list(map(str.strip, linesBefore))
            history.append(line.rstrip())
            append = [f.readline() for _ in range(4)]
            append = list(map(str.strip, append))
            f.seek(posn)  # Retore file position to where following line began.

        linesBefore.append(line)
        print(line.rstrip())

如果您使用的是 Python 3.8+,则可以使用该版本中添加的“海象”赋值运算符稍微简化循环。

import collections

with open("data_text.txt", "r") as f:
    linesBefore = collections.deque(maxlen=4)

    while (line := f.readline().rstrip()):
        if "george" in line:
            posn = f.tell()  # Save where next line starts.
            history = list(map(str.strip, linesBefore))
            history.append(line.rstrip())
            append = [f.readline() for _ in range(4)]
            append = list(map(str.strip, append))
            f.seek(posn)  # Retore file position to where following line began.

        linesBefore.append(line)
        print(line.rstrip())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM