繁体   English   中英

Python 3中的迭代器

[英]Iterators in Python 3

在Python 3中,许多返回列表的函数(现在是类)现在返回iterables,最常见的例子是range 在这种情况下,范围在Python 3中是可迭代的,以提高性能和内存效率(因为您不必再​​构建列表)。

其他“新” iterables是mapenumeratezip和字典操作的输出dict.keys() dict.values()dict.items() (可能还有更多,但我不知道)。

其中一些( enumeratemap )通过将它们转换为迭代可能变得更有效。 在Python 2.7中,其他人只是创建了已经在内存中的对象列表,因此它们可以提高内存效率。

为什么然后将它们变成可以在每次要对它们进行排序时必须转换为列表的迭代,等等?

几个原因:

  1. 字典操作现在返回字典视图对象 ; 这些也可以作为集合,为您提供更丰富的对象,以便在您的代码中使用。 在Python 2中,你必须使用dict.view*()方法来做同样的事情。

  2. Python 2中的字典操作产生了一个新的列表对象; 即使索引引用现有对象,列表对象也会占用内存。 这里还有另一个副作用; 列表索引会增加所有这些字典内容的引用计数,这也会影响性能(并且可能会刷新CPU缓存)。

  3. zip()map()总是可以处理任何迭代,包括生成器,但是在应用时会将所有内容都拉到一个大的列表中。 通过在Python 3中将它们转换为生成器,它们不再自动消耗这样的迭代。

请注意,Python 2中的enumerate()从未返回过列表,它总是返回一个迭代器。

只需在这些对象上应用list()就可以始终获得旧的Python 2行为。 如果你需要排序的项目,你可以在iterable上调用sorted() 但是你现在可以选择而不是强制列表对象。

对于Python中的大多数用例,您从未真正需要一个完整的列表。 您通常会迭代这些结果。 对它们进行排序不是最常见的用例,索引它们也不是。 因此,对于大多数用例而言,更改是一种胜利,为程序员提供了仅使用标准函数和类型生成更高效代码的工具。

如果你想对它们进行排序,那么迭代需要转换成一个列表( sorted将为你处理)...但是你要多久经常对一个enumerate对象进行排序,与你再次迭代的频率相比超过它? 那么对dict的items进行排序,与仅仅迭代它们相比呢?

如果您的API生成了一个惰性迭代器或其他惰性迭代器,您可以将其转换为一个列表,与跳过迭代器并直接生成列表所花费的工作量大致相同。 另一方面,如果您的API生成一个列表,则无法避免一次性将所有项目保留在内存中。 迭代器更灵活。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM