在Python 2.7中逐字迭代大型文件时的MemoryError

在Python 2.7中逐字迭代大型文件时的MemoryError,python,iterator,out-of-memory,Python,Iterator,Out Of Memory,我需要多次读取一个大文件,并需要访问文件中的总字数。我实现了一个包装类,其中包含一个迭代器、迭代器的副本(用于重置迭代器)及其长度: Class DataWrapper(object): def __init__(self, data): self.data, self.copy = itertools.tee(data) self.length = None def __iter__(self): return self.data def next(se

我需要多次读取一个大文件,并需要访问文件中的总字数。我实现了一个包装类,其中包含一个迭代器、迭代器的副本(用于重置迭代器)及其长度:

Class DataWrapper(object):
  def __init__(self, data):
    self.data, self.copy = itertools.tee(data)
    self.length = None

  def __iter__(self):
    return self.data

  def next(self):
    return self.data.next()

  def reset(self):
    self.data, self.copy = itertools.tee(self.copy)

  def __len__(self):
    if self.length is None:
      self.data, dcopy = itertools.tee(self.data)
      self.length = sum(1 for x in dcopy)
    return self.length
然后创建实际的文件读取迭代器并开始迭代:

def my_iter(fname):
  with open(fname, 'r') as f:
    for line in f:
      for word in line.split():
        yield word

dw = DataWrapper(my_iter("large_file.txt"))
for w in dw:
    pass
但出于某种原因,我在迭代时得到了一个
MemoryError

def my_iter(fname):
  with open(fname, 'r') as f:
    for line in f:
      for word in line.split():
        yield word

dw = DataWrapper(my_iter("large_file.txt"))
for w in dw:
    pass
文件“my_script.py”,第164行,在my_iter中 对于f中的行: 记忆者


因为没有包装就不会发生这种情况,所以我认为这应该受到责备。但是,是否有其他方法重置迭代器?

这里的问题是,如果数据只读取一次,并且必须多次迭代,则必须将其保存在内存中。如果文件足够大,足以耗尽内存,则以MemoryError结束。在这里,
itertool.tee
确实是罪魁祸首,即使我不认为它是罪魁祸首,因为它没有其他办法;-)


如果无法将数据保存在内存中,唯一简单的方法是为每个迭代器打开一个新的文件处理程序,前提是操作系统和文件系统允许。这样,内存将只包含一个缓冲区,每个迭代器只包含一行,而不是整个文件。

这里的问题是,如果数据只读取一次,并且必须多次迭代,那么它必须保存在内存中。如果文件足够大,足以耗尽内存,则以MemoryError结束。在这里,
itertool.tee
确实是罪魁祸首,即使我不认为它是罪魁祸首,因为它没有其他办法;-)


如果无法将数据保存在内存中,唯一简单的方法是为每个迭代器打开一个新的文件处理程序,前提是操作系统和文件系统允许。这样,内存将只包含一个缓冲区和每个迭代器一行,而不是整个文件。

请回答您的问题并包括错误的详细信息。它发生在哪一行?我同意——这可能是
itertools.tee
的工作。据我所知,在不保留数据缓存的情况下,无法重置此迭代器。但是,如果围绕文件对象而不是迭代器进行抽象,则可以
.seek
返回到特定的文件位置…From:“此itertool可能需要大量的辅助存储(取决于需要存储的临时数据量)。通常,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,那么使用list()而不是tee()会更快。“还有一些可能有用,也可能没有帮助的…@niefpaarschoenen为什么不打开一个新的文件句柄并创建一个新的迭代器呢?请回答您的问题并包括错误的详细信息。它发生在哪一行?我同意——这可能是
itertools.tee
的工作。据我所知,在不保留数据缓存的情况下,无法重置此迭代器。但是,如果围绕文件对象而不是迭代器进行抽象,则可以
.seek
返回到特定的文件位置…From:“此itertool可能需要大量的辅助存储(取决于需要存储的临时数据量)。一般来说,如果一个迭代器在另一个迭代器启动之前使用了大部分或全部数据,那么使用list()而不是tee()会更快。“还有一些可能有用,也可能没有帮助的…@niefpaarschoenen为什么不打开一个新的文件句柄并创建一个新的迭代器呢?