如何逐行读取大文件?

新手上路,请多包涵

我想遍历整个文件的每一行。一种方法是读取整个文件,将其保存到列表中,然后遍历感兴趣的行。此方法使用大量内存,因此我正在寻找替代方法。

到目前为止我的代码:

 for each_line in fileinput.input(input_file):
    do_something(each_line)

    for each_line_again in fileinput.input(input_file):
        do_something(each_line_again)

执行此代码会给出一条错误消息: device active

有什么建议么?

目的是计算成对的字符串相似度,这意味着对于文件中的每一行,我想计算与其他每一行的 Levenshtein 距离。

2022 年 11 月编辑:这个问题 8 个月后提出的相关问题有很多有用的答案和评论。要更深入地了解 python 逻辑,请阅读相关问题 How should I read a line-by-line in Python?

原文由 384X21 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 438
2 个回答

读取文件的正确、完全 Pythonic 方式如下:

 with open(...) as f:
    for line in f:
        # Do something with 'line'

with 语句处理打开和关闭文件,包括是否在内部块中引发异常。 for line in f 将文件对象 f 视为可迭代对象,它会自动使用缓冲 I/O 和内存管理,因此您不必担心大文件。

应该有一种——最好只有一种——显而易见的方法来做到这一点。

原文由 Katriel 发布,翻译遵循 CC BY-SA 4.0 许可协议

两种按顺序排列的内存有效方法(第一个是最好的)-

  1. 使用 with - python 2.5 及以上版本支持
  2. 使用 yield 如果你真的想控制阅读量

1.使用 with

with 是读取大文件的漂亮而高效的 pythonic 方式。优点 - 1) 文件对象在退出 with 执行块后自动关闭。 2) with 块内的异常处理。 3)内存 for 循环逐行遍历 f 文件对象。在内部,它执行缓冲 IO(以优化昂贵的 IO 操作)和内存管理。

 with open("x.txt") as f:
    for line in f:
        do something with data

2.使用 yield

有时,人们可能希望对每次迭代中读取的内容进行更细粒度的控制。在那种情况下使用 iter & yield 。请注意,使用此方法时,明确需要在最后关闭文件。

 def readInChunks(fileObj, chunkSize=2048):
    """
    Lazy function to read a file piece by piece.
    Default chunk size: 2kB.

    """
    while True:
        data = fileObj.read(chunkSize)
        if not data:
            break
        yield data

f = open('bigFile')
for chunk in readInChunks(f):
    do_something(chunk)
f.close()


陷阱和为了完整性 - 下面的 方法对于读取大文件来说不是那么好或不够优雅,但请阅读以获得全面的理解。

在 Python 中,从文件中读取行的最常见方法是执行以下操作:

 for line in open('myfile','r').readlines():
    do_something(line)

但是,完成此操作后, readlines() 函数(同样适用于 read() 函数)将整个文件加载到内存中,然后对其进行迭代。对于大文件,稍微好一点的方法(前面提到的两种方法是最好的)是使用 fileinput 模块,如下:

 import fileinput

for line in fileinput.input(['myfile']):
    do_something(line)

fileinput.input() 调用顺序读取行,但在读取后不会将它们保存在内存中,甚至只是这样,因为 file 在 python 中是可迭代的。

参考

  1. 带有语句的 Python

原文由 Srikar Appalaraju 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题