与文本文件几乎相同:将整个内容读入列表,然后倒退:
import csvwith 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 osdef 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到代码扭转线 之前, 他们到达
csv.reader,因而无需再
reversed和
list:
import csvwith open('test.csv', 'r') as textfile: for row in csv.reader(reversed_lines(textfile)): print ', '.join(row)还有一种可能更Python化的解决方案,它不需要在内存中逐个字符地反转该块(提示:只需获取该块中有行尾的索引列表,然后对其进行反转,然后将其用于对块进行切片),然后使用
chainout
itertools将来自连续块的线簇粘合在一起,但这留给读者练习。
值得注意的是,上面的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方言不使用,则需要更改引号字符
"。



