首页 > 解决方案 > 防止 itertools.islice 修改行

问题描述

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

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”不在输出中之后抓取的文本

apple
banana
carrot
dog
egg
food
george
lemon
mango

标签: python

解决方案


next()您可以通过在看到目标行时保存和恢复文件的当前位置来做到这一点 - 但是您不能在 using 时使用(直接或间接通过for line in file:or 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())

推荐阅读