python`list`和`for`返回不同的结果

时间:2014-11-07 16:43:02

标签: python list generator

如果我在我的函数生成的值上使用它们,为什么listfor会报告不同的结果?

from collections import deque

def neighbours(comp0, cand0):
    comp = deque([i for i in comp0])
    cand = deque([i for i in cand0])

    for i in range(len(cand)):
        elem = cand.popleft()
        comp.append(elem)
        yield comp, cand 
        comp.pop()
        cand.append(elem)

    return


>>> n = neighbours([2], [1,4,5])
>>> list(n)
[(deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5]))]
>>> n = neighbours([2], [1,4,5])
>>> for i in n:
...  print(i)
... 
(deque([2, 1]), deque([4, 5]))
(deque([2, 4]), deque([5, 1]))
(deque([2, 5]), deque([1, 4]))
>>> 

2 个答案:

答案 0 :(得分:4)

您的对象会在您迭代时被修改;使用for时打印中间结果,打印列表时最终结果。

如果您先将结果附加到列表中,则会再次获得与list()输出相同的结果:

>>> n = neighbours([2], [1,4,5])
>>> res = []
>>> for i in n:
...     print(i)
...     res.append(i)
... 
(deque([2, 1]), deque([4, 5]))
(deque([2, 4]), deque([5, 1]))
(deque([2, 5]), deque([1, 4]))
>>> res
[(deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5]))]

res中的每个元素都是一个元组,其中相同的两个双端对象

>>> res[0][0] is res[1][0] is res[2][0]
True
>>> res[0][1] is res[1][1] is res[2][1]
True

您可以生成每个list()的{​​{1}}份副本,从而创建新的对象:

deque

答案 1 :(得分:0)

Javier 已经很好地解释了问题的原因。现在,如果您希望使用迭代获得相同的结果,则可以使用:

>>> [i for i in n]
[(deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5])), (deque([2]), deque([1, 4, 5]))]