我正在阅读What does the "yield" keyword do in Python?的电子满意答案。他说:
这些迭代很方便,因为你可以根据自己的意愿阅读它们,但是你将所有的值存储在内存中,当你有很多值时,这并不总是你想要的
我不是很同意。但我不能在那里发表评论。
接下来是这个问题:Python的迭代是否真的将所有值存储在内存中?
我曾经这么认为。但是我改变了自己的观点,因为我昨天看到了Python的详细文档。
>>> import sys
>>> def gen():
... n = 0
... while n < 10:
... yield n
... n += 1
...
>>> a = [0,1,2,3,4,5,6,7,8,9]
>>> b = range(10) # b is a range object, which is a iterable
>>> c = gen(10) # c is a iterator, which is a iterable too
>>> sys.getsizeof(a)
144
>>> sys.getsizeof(b)
48
>>> sys.getsizeof(c)
72
>>> B = list(b)
>>> C = list(c)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> B
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> C
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> sys.getsizeof(B)
200
>>> sys.getsizeof(C)
160
我们错误地认为iterable将所有值存储在内存中,因为我们习惯于在使用iterable时获取所有值。
我是对的吗?
答案 0 :(得分:6)
在引用该答案时,您剥离了太多上下文。它是在像列表这样的迭代的上下文中特别制作的。生成器和as.character(sample(sample.letters,1))
关键字将在答案后面单独介绍。
扩展你的报价:
你可以使用的所有东西&#34; for ... in ...&#34; on是可迭代的;名单, 字符串,文件...
这些迭代很方便,因为你可以像你一样阅读它们 希望,但您将所有值存储在内存中并不总是这样 当你有很多价值时你想要什么。
对于列表和字符串,声明是正确的,它们存储在内存中。但是对于文件是不正确的,因为您可以迭代文件而不将其全部存储在内存中。
python iterable可能会也可能不会将值存储在内存中。它逐步执行一个值,并且在每个步骤中它可以从内存中提取值,从头开始创建它,或者从另一个源(如文件)中读取它。
yield
是一个很好的例子:在Python 2.x中它预先生成所有值并将它们存储在内存中,在Python 3.x中它根据需要生成它们。两者都返回一个可迭代的对象。