Python Py3k通过返回迭代器而不是列表来节省内存
在Python2.x中用于返回列表的许多方法现在似乎在Py3k中返回迭代器 迭代器也是生成器表达式吗?懒惰评估 这样,python的内存占用将大大减少。不是吗 使用内置脚本从2to3转换而来的程序如何Python Py3k通过返回迭代器而不是列表来节省内存,python,memory,list,iterator,python-3.x,Python,Memory,List,Iterator,Python 3.x,在Python2.x中用于返回列表的许多方法现在似乎在Py3k中返回迭代器 迭代器也是生成器表达式吗?懒惰评估 这样,python的内存占用将大大减少。不是吗 使用内置脚本从2to3转换而来的程序如何 为了兼容性,内置工具是否显式地将所有返回的迭代器转换为列表?如果是这样的话,那么Py3k较低的内存占用优势在转换的程序中并不明显。是吗?它们中的许多并不完全是迭代器,而是特殊的视图对象。例如,range()现在返回与旧的xrange对象类似的内容—它仍然可以被索引,但可以根据需要惰性地构造整数 类
为了兼容性,内置工具是否显式地将所有返回的迭代器转换为列表?如果是这样的话,那么Py3k较低的内存占用优势在转换的程序中并不明显。是吗?它们中的许多并不完全是迭代器,而是特殊的视图对象。例如,range()现在返回与旧的xrange对象类似的内容—它仍然可以被索引,但可以根据需要惰性地构造整数 类似地,dict.keys()给出了一个dict_keys对象,该对象在dict上实现了一个视图,而不是创建一个包含键副本的新列表 这对内存占用的影响可能取决于程序。当然,除非您真的需要列表,否则更多的是强调使用迭代器,而在python2中,使用列表通常是默认情况。这将导致平均程序的内存效率可能更高。在python2程序中,节省大量内存的情况可能已经被实现为迭代器,然而,真正大的内存使用将脱颖而出,并且更有可能已经得到解决。(例如,文件迭代器已经比旧的
file.readlines()
方法内存效率更高)
转换由2to3工具完成,通常会将range()等转换为迭代器,在迭代器中可以安全地确定不需要真正的列表,因此代码如下:
for x in range(10): print x
x = range(20)
将切换到新的range()对象,不再创建列表,因此将获得减少内存的好处,但代码如下:
for x in range(10): print x
x = range(20)
将转换为:
x = list(range(20))
因为转换器无法知道代码是否需要x中的真实列表对象
迭代器也是生成器表达式吗?懒惰评估
迭代器只是具有下一个方法的对象。当说明函数返回迭代器时,文档在大多数情况下的意思是它的结果是延迟加载的
这样,python的内存占用将大大减少。不是吗
视情况而定。我猜普通的程序不会注意到巨大的差异。迭代器相对于列表的性能优势只有在拥有大型数据集的情况下才有意义。您可能想看看。迭代器对列表的最大好处不是内存,而是计算时间。例如,在Python 2中:
for i in range(1000000): # spend a bunch of time making a big list
if i == 0:
break # Building the list was a waste since we only looped once
举个例子:
for i in xrange(1000000): # starts loop almost immediately
if i == 0:
break # we did't waste time even if we break early
尽管这个例子是人为设计的,但用例并非如此:循环经常在中途中断。建立一个完整的列表只使用其中的一部分是一种浪费,除非你打算多次使用它。如果是这种情况,您可以显式地构建一个列表:r=list(范围(100))
。这就是为什么在Python3中,迭代器在很多地方是默认的;因为您仍然可以在需要时显式地创建列表(或其他容器),所以您不需要任何东西。但当您计划只对一个iterable进行一次迭代时(我认为这是更常见的情况),您不会被迫这样做