【发布时间】:2016-01-24 00:06:38
【问题描述】:
我试图使用生成器来节省一些内存,但遇到了问题。我对结果有点惊讶,因为我的理解是整数是不可变的,所以有人可以解释发生了什么吗?
>>>> a = []
>>>> for i in range(10):
.... a.append((i for _ in [0]))
....
>>>> list(a[0])
[9]
当我使用列表推导来代替它时,它会做我想做的事:
>>>> a = []
>>>> for i in range(10):
.... a.append([i for _ in [0]])
....
>>>> a
[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]]
我可以有理由认为,发生的事情是生成器以某种方式获得了对i 值的“引用”,在最后一次循环之后是 9,但这似乎是反 Python 的python 没有这样的引用(至少据我所知)。
问题:
- 这是怎么回事?这怎么可能?我们将不胜感激提供一些 Python 文档的链接,这些文档可以准确解释正在发生的事情。
- 我怎样才能做我想做的事(使用带有变量的生成器,该变量将来会发生变化,但我需要当前值来做某事)?
更新:
现实用例:
def get_some_iter(a, b):
iters = []
for i in a:
m = do_something(i, len(b))
iters.append((SomeObj(j, m) for j in itertools.combinations(b, i))
return itertools.chain(*iters)
【问题讨论】:
-
在循环结束之前不要在 gen exp 中使用 i,因此 i 指向 9,列表 comp 将每个 i 附加到循环中,这正是您所期望的。你到底想做什么?
-
生成器表达式创建了一个生成器对象。我假设该对象将引用我使用的所有内容,而不是引用它似乎正在做的引用。例如,如果我在一个函数中完成了这一切,然后我超出了范围,那么我将如何使用生成器?
-
您正在附加一个引用
i的生成器,当循环完成时 i 为 9,即当您消耗生成器时,您得到 9,它距离如何一个 lambda 在循环中工作,lambda i=i:和lambda i:之间的区别。你能添加一个小的现实用例吗? -
你真的想做
yield from (SomeObj(j, m) for j in itertools.combinations(b, i)这样的事情吗? -
我猜是这样,除了我使用的是 python2.7 :(
标签: python reference generator