2015-07-28 19 views
5

Ecco il mio generatore:Perché questo generatore python restituisce sempre lo stesso valore?

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 

Ed ecco l'output, quando lo chiamo io:

>>> 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]] 

Se eseguo nuovamente l'istruzione, ho qualcosa di diverso [2, 0] (a causa di np.random chiamata), ma lo stesso valore in tutto .

risposta

4

Si sta riutilizzando lo stesso oggetto elenco. Il generatore restituisce l'un oggetto più e più volte, manipolando come va, ma tutti gli altri riferimenti ad esso vedere quelle stesse modifiche:

>>> 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]] 

produrre un copia della lista o di creare un nuovo oggetto lista fresco invece di manipolarne uno.

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

Sei yielding stesso list/object così si vedono sempre gli ultimi valori aggiunti alla lista. Si dovrebbe produrre una copia:

yield state[:] 

o creare la lista all'interno del primo ciclo:

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

Sarebbe così facile da aggiungere a una lista vuota nel ciclo interno, la creazione di una nuova lista/oggetto ogni volta:

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 
Problemi correlati