【问题标题】:Efficiently delete first element of a list有效删除列表的第一个元素
【发布时间】:2016-04-16 15:08:13
【问题描述】:

我正在编写一个程序,它可以读取数百万份学术论文摘要并从中收集一些数据。我一直遇到内存不足的问题,并且几乎尽我所能缩小规模。

我的下一个想法是在我的程序读完摘要后从内存中删除它。这是我的循环:

for i in range(0, len(abstracts)):
        abstract = abstracts[i]
        name = abstract.id
        self.Xdict[name] = self.Xdata.getData(abstract)
        self.Ydict[name] = self.Ydata.getData(abstract)
        sys.stdout.write("\rScanned Papers: %d" % count) #A visual counter
        sys.stdout.flush()
        count += 1
    sys.stdout.write("\rScanned Papers: %d" % count)
    sys.stdout.flush()

这是我的代码,没有任何从内存中删除项目的方法。我目前尝试使用:

del abstracts[0]  # This is too slow
abstracts = abstracts[1:]   # This is way too slow
abstract = abstracts.pop(0)  # Doesn't seem to free up any memory

任何帮助都会很棒。

谢谢!

【问题讨论】:

  • 顺便说一句,删除第一个元素是pop(0)
  • 谢谢,我试试看。
  • 你已经找到了del abstracts[0],并且在cmets中已经提到了abstracts.pop(0)。但我认为你问错了问题!正如您所发现的,在处理大量数据时,您不应该一次将其全部保存在内存中。在您的情况下,我会尝试的第一件事是迭代您的“摘要”而不将它们全部保存在列表中(或任何其他内存数据结构)。例如,如果每个都是文本文件中的一行,您可以使用 for abstract in open('path/to/file.txt', 'r'): ... 而不是首先将整个文件的内容读入内存。
  • 如何分批拆分处理而不是将它们全部添加到一个巨大的列表中?此外,pop(0)O(N),如果您要在数据结构的开始和结束处寻找快速删除,请查看collections.deque
  • 另外我建议使用tqdm 库来显示进度,而不是到处使用sys.stdout.write(); sys.stdout.flush()

标签: python memory memory-management out-of-memory


【解决方案1】:

要释放与O(1) 中每个摘要相关的内存,您可以这样做

abstracts[i] = None

处理后;这将只保留一个指针,并且会非常快。

然而,最好不要预先阅读所有摘要,除非您出于问题中未指定的原因确实需要这样做。

另请注意,支持从序列两端快速追加/删除元素的 Python 数据结构是 deque,而不是列表。

【讨论】:

    【解决方案2】:

    如果可能的话,您可以将摘要拆分为 10 Gb 数据,首先读取 1 gb 处理它,然后再读取 1 gb,这样处理起来很容易,不会占用太多时间和内存

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2017-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多