Python 如何以相反的顺序读取文件?

Python 如何以相反的顺序读取文件?,python,file,reverse,Python,File,Reverse,如何使用python以相反的顺序读取文件?我想把一个文件从最后一行读到第一行 for line in reversed(open("filename").readlines()): print line.rstrip() 在Python 3中: for line in reversed(list(open("filename"))): print(line.rstrip()) with open('filename', 'r') as f: for line in r

如何使用python以相反的顺序读取文件?我想把一个文件从最后一行读到第一行

for line in reversed(open("filename").readlines()):
    print line.rstrip()
在Python 3中:

for line in reversed(list(open("filename"))):
    print(line.rstrip())
with open('filename', 'r') as f:
    for line in reversed(list(f.readlines())):
        print(line)
在Python 3中:

for line in reversed(list(open("filename"))):
    print(line.rstrip())
with open('filename', 'r') as f:
    for line in reversed(list(f.readlines())):
        print(line)
如果您在linux上,可以使用
tac
命令

$ tac file
你可以在ActiveState和

如果您在linux上,可以使用
tac
命令

$ tac file
您可以在ActiveState中找到2个配方,然后重新导入 def filerev(somefile,缓冲区=0x20000): somefile.seek(0,os.seek\u END) size=somefile.tell() 行=[''] rem=缓冲区大小% 位置=最大值(0,(大小//缓冲区-1)*缓冲区) 当pos>=0时: somefile.seek(位置、操作系统seek\u集) data=somefile.read(rem+buffer)+行[0] 雷姆=0 lines=re.findall(“[^\n]*\n?”,数据) ix=长度(线)-2 当ix>0时: 屈服线[ix] ix-=1 pos-=缓冲区 其他: 屈服线[0] 将open(sys.argv[1],'r')作为f: 对于文件中的行版本(f): 系统标准输出写入(行)
重新导入
def filerev(somefile,缓冲区=0x20000):
somefile.seek(0,os.seek\u END)
size=somefile.tell()
行=['']
rem=缓冲区大小%
位置=最大值(0,(大小//缓冲区-1)*缓冲区)
当pos>=0时:
somefile.seek(位置、操作系统seek\u集)
data=somefile.read(rem+buffer)+行[0]
雷姆=0
lines=re.findall(“[^\n]*\n?”,数据)
ix=长度(线)-2
当ix>0时:
屈服线[ix]
ix-=1
pos-=缓冲区
其他:
屈服线[0]
将open(sys.argv[1],'r')作为f:
对于文件中的行版本(f):
系统标准输出写入(行)

我不久前不得不这样做,并使用了下面的代码。它通过管道与外壳相连。恐怕我没有完整的剧本了。如果您在unixish操作系统上,可以使用“tac”,但是在例如Mac OSX tac命令不起作用的情况下,请使用tail-r。下面的代码段测试您所处的平台,并相应地调整命令

# We need a command to reverse the line order of the file. On Linux this
# is 'tac', on OSX it is 'tail -r'
# 'tac' is not supported on osx, 'tail -r' is not supported on linux.

if sys.platform == "darwin":
    command += "|tail -r"
elif sys.platform == "linux2":
    command += "|tac"
else:
    raise EnvironmentError('Platform %s not supported' % sys.platform)

不久前我不得不这样做,并使用了下面的代码。它通过管道与外壳相连。恐怕我没有完整的剧本了。如果您在unixish操作系统上,可以使用“tac”,但是在例如Mac OSX tac命令不起作用的情况下,请使用tail-r。下面的代码段测试您所处的平台,并相应地调整命令

# We need a command to reverse the line order of the file. On Linux this
# is 'tac', on OSX it is 'tail -r'
# 'tac' is not supported on osx, 'tail -r' is not supported on linux.

if sys.platform == "darwin":
    command += "|tail -r"
elif sys.platform == "linux2":
    command += "|tac"
else:
    raise EnvironmentError('Platform %s not supported' % sys.platform)

在这里你可以找到我的我的实现,你可以通过改变“buffer”变量来限制ram的使用,有一个bug,程序在开始时打印一个空行

而且,如果没有超过缓冲区字节的新行,“leak”变量将增加,直到看到新行(“\n”)为止,ram使用量也可能会增加

这也适用于16GB的文件,比我的总内存大

import os,sys
buffer = 1024*1024 # 1MB
f = open(sys.argv[1])
f.seek(0, os.SEEK_END)
filesize = f.tell()

division, remainder = divmod(filesize, buffer)
line_leak=''

for chunk_counter in range(1,division + 2):
    if division - chunk_counter < 0:
        f.seek(0, os.SEEK_SET)
        chunk = f.read(remainder)
    elif division - chunk_counter >= 0:
        f.seek(-(buffer*chunk_counter), os.SEEK_END)
        chunk = f.read(buffer)

    chunk_lines_reversed = list(reversed(chunk.split('\n')))
    if line_leak: # add line_leak from previous chunk to beginning
        chunk_lines_reversed[0] += line_leak

    # after reversed, save the leakedline for next chunk iteration
    line_leak = chunk_lines_reversed.pop()

    if chunk_lines_reversed:
        print "\n".join(chunk_lines_reversed)
    # print the last leaked line
    if division - chunk_counter < 0:
        print line_leak
导入操作系统,系统 缓冲区=1024*1024#1MB f=打开(系统argv[1]) f、 寻道(0,操作系统寻道结束) filesize=f.tell() 除法,余数=divmod(文件大小,缓冲区) 行_泄漏=“” 对于范围(1,除法+2)内的块计数器: 如果除法-块计数器<0: f、 寻道(0,操作系统寻道集) chunk=f.read(余数) elif除法-块计数器>=0: f、 seek(-(缓冲区*块计数器),操作系统seek\u结束) chunk=f.read(缓冲区) chunk\u line\u reversed=列表(已反转(chunk.split('\n')) 如果行_泄漏:#将前一块中的行_泄漏添加到开头 块\u行\u反转[0]+=行\u泄漏 #反转后,将泄漏的行保存到下一个块迭代中 line\u leak=chunk\u line\u reversed.pop() 如果区块线反转: 打印“\n”。连接(块\u行\u反转) #打印最后一行 如果除法-块计数器<0: 打印线泄漏
在这里您可以找到my my实现,您可以通过更改“buffer”变量来限制ram的使用,有一个错误,程序在开始时打印一个空行

而且,如果没有超过缓冲区字节的新行,“leak”变量将增加,直到看到新行(“\n”)为止,ram使用量也可能会增加

这也适用于16GB的文件,比我的总内存大

import os,sys
buffer = 1024*1024 # 1MB
f = open(sys.argv[1])
f.seek(0, os.SEEK_END)
filesize = f.tell()

division, remainder = divmod(filesize, buffer)
line_leak=''

for chunk_counter in range(1,division + 2):
    if division - chunk_counter < 0:
        f.seek(0, os.SEEK_SET)
        chunk = f.read(remainder)
    elif division - chunk_counter >= 0:
        f.seek(-(buffer*chunk_counter), os.SEEK_END)
        chunk = f.read(buffer)

    chunk_lines_reversed = list(reversed(chunk.split('\n')))
    if line_leak: # add line_leak from previous chunk to beginning
        chunk_lines_reversed[0] += line_leak

    # after reversed, save the leakedline for next chunk iteration
    line_leak = chunk_lines_reversed.pop()

    if chunk_lines_reversed:
        print "\n".join(chunk_lines_reversed)
    # print the last leaked line
    if division - chunk_counter < 0:
        print line_leak
导入操作系统,系统 缓冲区=1024*1024#1MB f=打开(系统argv[1]) f、 寻道(0,操作系统寻道结束) filesize=f.tell() 除法,余数=divmod(文件大小,缓冲区) 行_泄漏=“” 对于范围(1,除法+2)内的块计数器: 如果除法-块计数器<0: f、 寻道(0,操作系统寻道集) chunk=f.read(余数) elif除法-块计数器>=0: f、 seek(-(缓冲区*块计数器),操作系统seek\u结束) chunk=f.read(缓冲区) chunk\u line\u reversed=列表(已反转(chunk.split('\n')) 如果行_泄漏:#将前一块中的行_泄漏添加到开头 块\u行\u反转[0]+=行\u泄漏 #反转后,将泄漏的行保存到下一个块迭代中 line\u leak=chunk\u line\u reversed.pop() 如果区块线反转: 打印“\n”。连接(块\u行\u反转) #打印最后一行 如果除法-块计数器<0: 打印线泄漏
作为生成器编写的正确、有效的答案

import os

def reverse_readline(filename, buf_size=8192):
    """A generator that returns the lines of a file in reverse order"""
    with open(filename) 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))
            remaining_size -= buf_size
            lines = buffer.split('\n')
            # The first line of the buffer is probably not a complete line so
            # we'll save it and append it to the last line of the next buffer
            # we read
            if segment is not None:
                # If the previous chunk starts right from the beginning of line
                # do not concat the segment to the last line of new chunk.
                # Instead, yield the segment first 
                if buffer[-1] != '\n':
                    lines[-1] += segment
                else:
                    yield segment
            segment = lines[0]
            for index in range(len(lines) - 1, 0, -1):
                if lines[index]:
                    yield lines[index]
        # Don't yield None if the file was empty
        if segment is not None:
            yield segment

作为生成器编写的正确、有效的答案

import os

def reverse_readline(filename, buf_size=8192):
    """A generator that returns the lines of a file in reverse order"""
    with open(filename) 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))
            remaining_size -= buf_size
            lines = buffer.split('\n')
            # The first line of the buffer is probably not a complete line so
            # we'll save it and append it to the last line of the next buffer
            # we read
            if segment is not None:
                # If the previous chunk starts right from the beginning of line
                # do not concat the segment to the last line of new chunk.
                # Instead, yield the segment first 
                if buffer[-1] != '\n':
                    lines[-1] += segment
                else:
                    yield segment
            segment = lines[0]
            for index in range(len(lines) - 1, 0, -1):
                if lines[index]:
                    yield lines[index]
        # Don't yield None if the file was empty
        if segment is not None:
            yield segment

像这样的怎么样:

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

由于文件是按相反的顺序逐字符读取的,因此即使在非常大的文件上也能工作,只要单个行适合内存。

类似这样的内容如何:

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

由于文件是按相反顺序逐字符读取的,因此即使在非常大的文件上也可以使用,只要内存中有单独的行。

创建第二个文件的简单函数(仅限linux):

如何使用

tac('ordered.csv', 'reversed.csv')
f = open('reversed.csv')

创建第二个文件的简单函数(仅限linux):

如何使用

tac('ordered.csv', 'reversed.csv')
f = open('reversed.csv')

在处理文件时,请始终将
一起使用,因为它可以为您处理一切:

with open('filename', 'r') as f:
    for line in reversed(f.readlines()):
        print line
或者在Python 3中:

for line in reversed(list(open("filename"))):
    print(line.rstrip())
with open('filename', 'r') as f:
    for line in reversed(list(f.readlines())):
        print(line)

在处理文件时,请始终将
一起使用,因为它可以为您处理一切:

with open('filename', 'r') as f:
    for line in reversed(f.readlines()):
        print line
或者在Python 3中:

for line in reversed(list(open("filename"))):
    print(line.rstrip())
with open('filename', 'r') as f:
    for line in reversed(list(f.readlines())):
        print(line)

您还可以使用python模块
文件\u向后读取

安装后,通过
pip安装文件\u向后读取
(v1.2.1),
def previous_line(self, opened_file):
        opened_file.seek(0, os.SEEK_END)
        position = opened_file.tell()
        buffer = bytearray()
        while position >= 0:
            opened_file.seek(position)
            position -= 1
            new_byte = opened_file.read(1)
            if new_byte == self.NEW_LINE:
                parsed_string = buffer.decode()
                yield parsed_string
                buffer = bytearray()
            elif new_byte == self.EMPTY_BYTE:
                continue
            else:
                new_byte_array = bytearray(new_byte)
                new_byte_array.extend(buffer)
                buffer = new_byte_array
        yield None
opened_file = open(filepath, "rb")
iterator = self.previous_line(opened_file)
line = next(iterator) #one step
close(opened_file)
from collections import deque

fs = open("test.txt","rU")
fr = deque(fs)
fr.reverse()  # reverse in-place, returns None

for li in fr:
   print li

fs.close()