gpt4 book ai didi

python - itertools.chain.from_iterable 的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-03 14:14:00 25 4
gpt4 key购买 nike

考虑这个代码片段:

>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain(*list(bar))
...
>>> list(foo)
[0, 1]

这是有道理的——在循环的第一次迭代中,bar 等同于 iter([[0]]) 而 foo 的计算结果为 chain( [0]),相当于iter([0])。然后,在循环的第二次迭代中,bar 现在等效于 iter([[0, 1]]) 而 foo 变为 iter([0, 1])。这就是为什么 list(foo)[0, 1]

当我使用 foo = sum(list(bar), []) 而不是 chain 时,我对 list(foo) 也得到相同的结果(*list(bar)).

现在考虑这个代码片段:

>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain.from_iterable(bar)
...
>>> list(foo)
[0, 1, 1, 2]

如您所见,唯一的区别是 foo = chain.from_iterable(bar) 行,它使用 itertools.chain.from_iterable而不是 itertools.chain

在我看来,itertools.chain(*list(iterable)) 大致等同于 itertools.chain.from_iterable(iterable),但事实并非如此这里。那为什么最后的结果不一样呢?

最佳答案

不同之处在于,在chain(*list(bar)) 中,bar 会立即耗尽,而在chain.from_iterable(bar) 中,不会。并且在 bar 的定义中,使用了 i,它是后期绑定(bind)的:它获取 i 的值,而不是在定义,而是从评估时的名称 i 开始。

IOW,当你使用 foo = chain.from_iterable(bar) 时,bar 还没有被评估。当您随后调用 list(foo) 时,它会“调用”bar,定义中的 i 会选取名称 i 当前指的是 -- 即 2。

因此,如果我们手动更改 i,我们应该能够适本地更改结果:

>>> from itertools import chain
>>> foo = [0]
>>> for i in (1, 2):
... bar = (range(a, a+i) for a in foo)
... foo = chain.from_iterable(bar)
...
>>> i = 10
>>> list(foo)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

关于python - itertools.chain.from_iterable 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35022197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com