Why is this python generator returning the same value everytime?

独自空忆成欢 提交于 2019-12-28 01:11:55

问题


I have this generator that yields lists:

def gen():
    state = [None]

    for i in range(5):
        state[0] = i
        yield state

And here's the output, when I call it:

>>> list(gen())
[[4], [4], [4], [4], [4]]

Why are all the elements [4]? Shouldn't it be [[0], [1], [2], [3], [4]]?


回答1:


You are reusing the same list object. Your generator returns the one object over and over again, manipulating it as it goes, but any other references to it see those same changes:

>>> r = list(gen())
>>> r
[[4], [4], [4], [4], [4]]
>>> r[0] is r[1]
True
>>> r[0][0] = 42
>>> r
[[42], [42], [42], [42], [42]]

Yield a copy of the list or create a new fresh list object instead of manipulating one.

def gen_copy():
    state = [None]

    for i in range(5):
        state[0] = i
        yield state.copy()  # <- copy

def gen_new():
    for i in range(5):
        state = [i]  # <- new list object every iteration
        yield state



回答2:


You are yielding the same list/object so you always see the last values added to the list. You should yield a copy:

yield state.copy()

Or create the list inside the first loop:

for i in range(5):
    state = [i]

It would be as easy to create a new list/object each time:

def gen():
    for i in range(5):
        state = [None]
        state[0] = i
        yield state


来源:https://stackoverflow.com/questions/31687185/why-is-this-python-generator-returning-the-same-value-everytime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!