python - 如何在 Python 中以相反的顺序读取 CSV 文件?

标签 python csv

我知道如何为 TXT 文件执行此操作,但现在我在为 CSV 文件执行此操作时遇到了一些问题。

如何在 Python 中从底部读取 CSV 文件?

最佳答案

与文本文件的方式几乎相同:将整个文件读入列表,然后倒退:

import csv
with open('test.csv', 'r') as textfile:
    for row in reversed(list(csv.reader(textfile))):
        print ', '.join(row)

如果你想变得更有趣,你可以编写大量代码,从文件末尾开始读取 block 并向后工作,一次发出一行,然后将其提供给 csv.reader,但这只适用于可以查找的文件,即磁盘文件而不是标准输入。


Some of us have files that do not fit into memory, could anyone come with a solution that does not require storing the entire file in memory?

这有点棘手。幸运的是,csv.reader 期望的是一个类似于迭代器的对象,每次调用 next() 时都会返回一个字符串(行)。因此,我们采用 Darius Bacon 在“Most efficient way to search the last x lines of a file in python”中介绍的技术来反向读取文件的行,而不必拉入整个文件:

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 馈送到代码中以反转 before 它们到达 csv.reader 的行,从而不再需要 reversed 列表:

import csv
with open('test.csv', 'r') as textfile:
    for row in csv.reader(reversed_lines(textfile)):
        print ', '.join(row)

有一个更 Pythonic 的解决方案可能,它不需要在内存中逐个字符地反转 block (提示:只需获取 block 中有行结束的索引列表,反转它,然后使用它来分割 block ),并使用 itertools 中的 chain 将连续 block 中的线簇粘合在一起,但这留给读者作为练习。


It's worth noting that the reversed_lines() idiom above only works if the columns in the CSV file don't contain newlines.

啊!总有一些东西。幸运的是,解决这个问题还算不错:

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 方言不使用 ",您将需要更改引号字符。

关于python - 如何在 Python 中以相反的顺序读取 CSV 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10933838/

相关文章:

python - 如何将文本导出到新文件、用户输入?

c# - 在 C# 中读取和更改 gridview 的值

python - Pandas :连接数据框并保留重复索引

python - 在 python 中计算频率的最干净的方法是什么

Python 将字典列表写入 csv

Python:如何将从操作获得的值添加到给定 CSV 的新列中?

Python Tkinter : Remove window border

python - 删除 Pandas Dataframe 中按其他列分组的列中频率最低的行

python - 下载后文件的可执行权限发生变化。是否有任何协议(protocol)或方法可以完好无损许可?

python - 如何将整个 SQL Server 表复制到 CSV(包括列标题)?