Вопрос-Ответ

How to read a file in reverse order?

Как прочитать файл в обратном порядке?

Как прочитать файл в обратном порядке с помощью python? Я хочу прочитать файл от последней строки до первой.

Переведено автоматически
Ответ 1

Правильный, эффективный ответ, написанный в виде генератора.

import os

def reverse_readline(filename, buf_size=8192):
"""A generator that returns the lines of a file in reverse order"""
with open(filename, 'rb') as fh:
segment = None
offset = 0
fh.seek(0, os.SEEK_END)
file_size = remaining_size = fh.tell()
while remaining_size > 0:
offset = min(file_size, offset + buf_size)
fh.seek(file_size - offset)
buffer = fh.read(min(remaining_size, buf_size))
# remove file's last "\n" if it exists, only for the first buffer
if remaining_size == file_size and buffer[-1] == ord('\n'):
buffer = buffer[:-1]
remaining_size -= buf_size
lines = buffer.split('\n'.encode())
# append last chunk's segment to this chunk's last line
if segment is not None:
lines[-1] += segment
segment = lines[0]
lines = lines[1:]
# yield lines in this chunk except the segment
for line in reversed(lines):
# only decode on a parsed line, to avoid utf-8 decode error
yield line.decode()
# Don't yield None if the file was empty
if segment is not None:
yield segment.decode()
Ответ 2
for line in reversed(open("filename").readlines()):
print line.rstrip()

И в Python 3:

for line in reversed(list(open("filename"))):
print(line.rstrip())
Ответ 3

Вы также можете использовать модуль python file_read_backwards.

После его установки через pip install file_read_backwards (версия 1.2.1) вы можете прочитать весь файл в обратном порядке (по строкам) с экономией памяти с помощью:

#!/usr/bin/env python2.7

from file_read_backwards import FileReadBackwards

with FileReadBackwards("/path/to/file", encoding="utf-8") as frb:
for l in frb:
print l

Он поддерживает кодировки "utf-8", "latin-1" и "ascii".

Поддержка также доступна для python3. Дополнительную документацию можно найти по адресу http://file-read-backwards.readthedocs.io/en/latest/readme.html

Ответ 4

Как насчет чего-то подобного:

import os


def readlines_reverse(filename):
with open(filename) as qfile:
qfile.seek(0, os.SEEK_END)
position = qfile.tell()
line = ''
while position >= 0:
qfile.seek(position)
next_char = qfile.read(1)
if next_char == "\n":
yield line[::-1]
line = ''
else:
line += next_char
position -= 1
yield line[::-1]


if __name__ == '__main__':
for qline in readlines_reverse(raw_input()):
print qline

Поскольку файл читается посимвольно в обратном порядке, он будет работать даже с очень большими файлами, пока отдельные строки умещаются в памяти.

python file