【问题标题】:Reading large file (52mb) of lines in Python, is it better to iterate the lines or use readlines?在 Python 中读取大文件(52mb)行,是迭代行还是使用 readlines 更好?
【发布时间】:2015-11-23 10:39:09
【问题描述】:

我有一个 txt 文件中包含 400 万个单词的列表,我想将其添加到列表中。我有两个选择:

l=[line for line in open(wordlist)]

或:

wordlist = file.readlines()

readlines() 似乎要快得多,我猜这是因为数据一次性读入内存。第一个选项会更好地节省内存,因为它一次读取一行,这是真的吗?复制时 readlines() 是否使用任何类型的缓冲区?一般来说哪个最好用?

【问题讨论】:

  • 如果您在两种情况下都有足够的内存空间来处理结果列表,您可以使用 readline() 一次读取一行或使用 readlines() 读取所有行...您将如何处理之后的单词列表,它将告诉您应该做什么......如果您不需要随时访问它们,拥有 400 万个单词列表是没有意义的。

标签: python file-io


【解决方案1】:

这两个选项都将整个内容读入内存中的一个大列表。第一个选项较慢,因为您将循环委托给 Python 字节码。如果您想创建一个包含文件中所有行的大列表,那么这里没有理由使用列表推导式。

我不会使用两者。循环文件并在循环时处理行

with open(wordlist) as fileobj:
    for line in fileobj:
        # do something with this line only.

通常不需要将整个未处理的文件数据保存在内存中。

【讨论】:

  • 但是第一个在逐行传输时会使用更少的内存吗?以前从未考虑过循环文件。我正在对列表进行二进制搜索,所以需要先对其进行排序。
  • @KexAri:列表推导使用的内存量与readlines() 调用大致相同;最后你得到了完全相同的对象。
【解决方案2】:

我认为真正的答案是,这取决于。

如果你有记忆,你用多少都没关系。然后,您可以通过 readlines() 方法将所有 400 万个字符串放入一个列表中。但是我会问是否真的有必要一次将它们全部保存在内存中?

可能更高效的方法是一次遍历每一行/单词,对那个单词做一些事情(计数、hashvectorize 等),然后让垃圾收集器把它带到转储。此方法使用一次弹出一行的生成器,而不是不必要地将所有内容读入内存。

Python 3.* 中的许多内置函数都转向这种生成器样式,one example is xrange vs range

【讨论】:

    【解决方案3】:

    考虑到您正在对列表进行二进制搜索,因此需要先对其进行排序。,您需要将数据读入列表并在具有 1000 万随机数字的文件上进行排序,调用readlines 和就地.sort 稍微快一些:

    In [15]: %%timeit
    with open("test.txt") as f:
         r = f.readlines()
         r.sort()
       ....: 
    1 loops, best of 3: 719 ms per loop
    
    In [16]: %%timeit
    with open("test.txt") as f:
        sorted(f)
       ....: 
    1 loops, best of 3: 776 ms per loop
    
    In [17]: %%timeit
    with open("test.txt") as f:
         r = [line for line in f] 
         r.sort()
       ....: 
    
    1 loops, best of 3: 735 ms per loop
    

    无论您使用哪种方法,列表中的数据都相同,因此没有内存优势,唯一的区别是 readlines 比列表组合或在文件对象上调用排序更有效。

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      相关资源
      最近更新 更多