一直在读Pep-0289。它提到了
sum(x*x for x in range(10))
将节省内存:
sum([x*x for x in range(10)])
我感到困惑的是range(10)
不能一次生成整个列表的原因。有什么地方,如果你在for-each构造中抛出range()
,它会自动成为迭代器吗?我认为答案是否定的,因为这是Python 2.x中的xrange()
。
继续沿着Pep说:
def __gen(exp):
for x in exp:
yield x**2
g = __gen(iter(range(10)))
print g.next()
在这里,他们使用iter
将range(10)
转换为迭代器。为什么在前面的示例中不需要iter
? [x for x in range(3)]
和[x for x in iter(range(3))]
是否以某种方式对待?
答案 0 :(得分:1)
以某种方式
[x for x in [1, 3, 4]]
和[x for x in iter([1, 3, 4])]
对待它?
它们具有相同的效果,是的。这一行:
[x for x in [1, 3, 4]]
隐式调用列表的__iter__
method来获取迭代器。它相当于:
[x for x in [1, 3, 4].__iter__()]
这一行:
[x for x in iter([1, 3, 4])]
使用iter
在列表上获取迭代器。它也相当于:
[x for x in [1, 3, 4].__iter__()]
除了它不必要地使用内置的iter
函数来执行for ... in ...
子句已经执行的操作。
更好地使用iter
是通过可迭代的逐步控制迭代。以下是一个例子:
it = iter(iterable)
item = next(it) # Get the first item in the iterator
while True:
# code
if condition:
item = next(it) # Advance the iterator only if condition is True
答案 1 :(得分:1)
range(10)
会立即生成整个列表。但这不是节省内存的部分。
此:
sum(x*x for x in range(10))
基本上会计算(或多或少)如下:
那就是它会单独计算每个,并且随着它的总和而计算
以下内容:
sum([x*x for x in range(10)])
而是首先创建一个完整的列表:
然后做总和。