2015-07-28 5 views
5

Hier ist mein Generator:Warum gibt dieser Python-Generator jedes Mal den gleichen Wert zurück?

import numpy as np 

def fun(): 
    state = [1, 2] 
    for i in range(10): 
     for j, var in enumerate(state): 
      next_st = np.random.randint(0, 3) 
      state[j] = next_st 
     yield state 

Und hier ist der Ausgang, wenn ich es nennen:

>>> g = fun(); y = [x for x in g]; y 
[[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0], 
[2, 0]] 

Wenn ich die Anweisung erneut ausführen, ich etwas anderes als [2, 0] (wegen np.random Anruf) erhalten, aber der gleiche Wert in allen y.

Antwort

4

Sie verwenden dasselbe Listenobjekt erneut. Ihr Generator liefert den ein Objekt immer und immer wieder, es zu manipulieren, wie es geht, aber alle anderen Verweise darauf, die gleichen Änderungen sehen:

>>> g = fun(); y = [x for x in g]; y 
[[2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1], [2, 1]] 
>>> y[0] is y[1] 
True 
>>> y[0][0] = 42 
>>> y 
[[42, 1], [42, 1], [42, 1], [42, 1], [42, 1], [42, 1], [42, 1], [42, 1], [42, 1], [42, 1]] 

Ausbeute eine Kopie der Liste oder erstellen Sie eine neue frische Liste Objekt anstatt einen zu manipulieren.

def fun(): 
    state = [1, 2] 
    for i in range(10): 
     for j, var in enumerate(state): 
      next_st = np.random.randint(0, 3) 
      state[j] = next_st 
     yield state[:] # copy 

def fun(): 
    for i in range(10): 
     state = [1, 2] # new list object each iteration 
     for j, var in enumerate(state): 
      next_st = np.random.randint(0, 3) 
      state[j] = next_st 
     yield state 
4

Sie sind yielding die gleiche list/object so immer Sie die letzten Werte in die Liste aufgenommen sehen. Sie sollten eine Kopie ergeben:

yield state[:] 

Oder die Liste innerhalb der ersten Schleife erstellen:

for i in range(10): 
     state = [1, 2] 

Es wäre so einfach auf eine leere Liste in der inneren Schleife anhängen, um eine neue Liste erstellen/Objekt jedes Mal: ​​

def fun(): 
    for i in range(10): 
     state = [] 
     for j in range(2): 
      next_st = np.random.randint(0, 3) 
      state.append(next_st) 
     yield state 
Verwandte Themen