我知道如何为 TXT 文件执行此操作,但现在我在为 CSV 文件执行此操作时遇到了一些麻烦。
如何在 Python 中从底部读取 CSV 文件?
与文本文件的方式几乎相同:将整个内容读入列表,然后倒退:
import csv
with open('test.csv', 'r') as textfile:
    for row in reversed(list(csv.reader(textfile))):
        print ', '.join(row)
如果你想变得花哨,你可以编写很多代码,从文件末尾开始读取块并向后工作,一次发出一行,然后将其提供给csv.reader,但这仅适用于一个文件可以查找,即磁盘文件但不是标准输入。
我们中的一些人有不适合内存的文件,任何人都可以提供不需要将整个文件存储在内存中的解决方案吗?
这有点棘手。幸运的是,所有csv.reader期望都是一个类似迭代器的对象,每次调用都会返回一个字符串(行)next()。因此,我们采用 Darius Bacon 在“在 python 中搜索文件的最后 x 行的最有效方法”中提出的技术来向后读取文件的行,而不必拉入整个文件:
import os
def reversed_lines(file):
    "Generate the lines of file in reverse order."
    part = ''
    for block in reversed_blocks(file):
        for c in reversed(block):
            if c == '\n' and part:
                yield part[::-1]
                part = ''
            part += c
    if part: yield part[::-1]
def reversed_blocks(file, blocksize=4096):
    "Generate blocks of file's contents in reverse order."
    file.seek(0, os.SEEK_END)
    here = file.tell()
    while 0 < here:
        delta = min(blocksize, here)
        here -= delta
        file.seek(here, os.SEEK_SET)
        yield file.read(delta)
并输入代码以在它们到达之前reversed_lines反转行,从而消除对and的需要:csv.readerreversedlist
import csv
with open('test.csv', 'r') as textfile:
    for row in csv.reader(reversed_lines(textfile)):
        print ', '.join(row)
有一个更 Pythonic 的解决方案可能,它不需要对内存中的块进行逐个字符的反转(提示:只需获取块中有行尾的索引列表,反转它,并使用它来切块),并使用chainoutitertools将连续块的线簇粘合在一起,但这留给读者作为练习。
值得注意的是,上面的 reversed_lines() 习惯用法仅在 CSV 文件中的列不包含换行符时才有效。
啊!总有一些东西。幸运的是,解决这个问题还不错:
def reversed_lines(file):
    "Generate the lines of file in reverse order."
    part = ''
    quoting = False
    for block in reversed_blocks(file):
        for c in reversed(block):
            if c == '"':
                quoting = not quoting
            elif c == '\n' and part and not quoting:
                yield part[::-1]
                part = ''
            part += c
    if part: yield part[::-1]
当然,如果您的 CSV 方言不使用".
以@mike-desimone 的回答为基础。这是一个解决方案,它提供与 python 文件对象相同的结构,但逐行反向读取:
import os
class ReversedFile(object):
    def __init__(self, f, mode='r'):
        """
        Wraps a file object with methods that make it be read in reverse line-by-line
        if ``f`` is a filename opens a new file object
        """
        if mode != 'r':
            raise ValueError("ReversedFile only supports read mode (mode='r')")
        if not type(f) == file:
            # likely a filename
            f = open(f)
        self.file = f
        self.lines = self._reversed_lines()
    def _reversed_lines(self):
        "Generate the lines of file in reverse order."
        part = ''
        for block in self._reversed_blocks():
            for c in reversed(block):
                if c == '\n' and part:
                    yield part[::-1]
                    part = ''
                part += c
        if part: yield part[::-1]
    def _reversed_blocks(self, blocksize=4096):
        "Generate blocks of file's contents in reverse order."
        file = self.file
        file.seek(0, os.SEEK_END)
        here = file.tell()
        while 0 < here:
            delta = min(blocksize, here)
            here -= delta
            file.seek(here, os.SEEK_SET)
            yield file.read(delta)
    def __getattribute__(self, name):
        """ 
        Allows for the underlying file attributes to come through
        """ 
        try:
            # ReversedFile attribute
            return super(ReversedFile, self).__getattribute__(name)
        except AttributeError:
            # self.file attribute
            return getattr(self.file, name)
    def __iter__(self):
        """ 
        Creates iterator
        """ 
        return self
    def seek(self):
        raise NotImplementedError('ReversedFile does not support seek')
    def next(self):
        """
        Next item in the sequence
        """
        return self.lines.next()
    def read(self):
        """
        Returns the entire contents of the file reversed line by line
        """
        contents = ''
        for line in self:
            contents += line
        return contents
    def readline(self):
        """
        Returns the next line from the bottom
        """
        return self.next()
    def readlines(self):
        """
        Returns all remaining lines from the bottom of the file in reverse
        """
        return [x for x in self]
    去吧。这是一个从 CSV 文件中反转行的简单程序。
import csv
BC_file = open('Master.csv', 'rb')
BC_reader = csv.reader(BC_file)
next(BC_reader)
for row in reversed(list(BC_reader)):
    print row[0]