Я читаю 3 строки за раз из файла с номерами 1,2,3... 100
Я хочу, чтобы результат выглядел примерно так. 1 2 3 2 3 4 3 4 5
Однако со следующим кодом он печатает непрерывные номера
with open("/home/osboxes/num", "r+") as f:
for line in f:
print(line)
line2 = f.__next__()
print(line2)
line3 = f.__next__()
print(line3)
Есть ли способ вернуться к итерации и пропустить строку файла и отобразить вывод, как показано выше
Предположим, что вместо вашего файлового объекта у нас есть итератор типа iter(range(100))
, чтобы произвести наш ожидаемый результат, используя next
вы можете копировать итератор с помощью itertools.tee
столько раз, сколько хотите, и создать zip
из своего итераторы на основе ожидаемого результата:
In [3]: r = iter(range(100))
In [4]: from itertools import tee
In [5]: r, n, m = tee(r, 3) # copy the iterator 3 times
In [6]: next(n) # consume the first item of n
Out[6]: 0
In [7]: next(m);next(m) # consume the first 2 items of m
Out[7]: 1
In [8]: list(zip(r, n, m))
#Out[8]:
#[(0, 1, 2),
# (1, 2, 3),
# (2, 3, 4),
# (3, 4, 5),
# (4, 5, 6),
# (5, 6, 7),
# ...
Теперь вы можете сделать то же самое с файлом:
from itertools import tee
with open("/home/osboxes/num", "r+") as f:
f, n, m = tee(f, 3)
next(n);next(m);next(m)
for i, j , k in zip(r, n, m):
print(i, j, k) # or do something else with i,j,k
Если это меньший файл, как вы упомянули, вы можете использовать следующий код, но если он намного больше, чем предпочитает метод seek()
:
with open("abc.txt", "r+") as f:
data = f.readlines()
for i in range(2, len(data)):
print("%s %s %s" % (data[i-2].rstrip(), data[i-1].rstrip(), data[i].rstrip()), end = " ")
Выход:
1 2 3 2 3 4 3 4 5
Если сохранение всего файла в переменной не является проблемой, простым решением будет:
with open("num", "r+") as f:
lines = f.read().splitlines()
for i in range(len(lines) - 2):
print(lines[i])
print(lines[i + 1])
print(lines[i + 2])
Для более эффективного решения см. Решение @Kasramvd с использованием итераторов.
В качестве альтернативы без итераторов вы можете сохранить последние 2 значения:
with open("num", "r+") as f:
prev1, prev2 = None, None
for line in f:
if prev1 is not None and prev2 is not None:
print(prev1)
print(prev2)
print(line)
prev1, prev2 = prev2, line