2009-12-24 24 views
10

pitone:lista Python problema

m=[[0]*3]*2 
for i in range(3): 
    m[0][i]=1 

print m 

mi aspetto che questo codice dovrebbe stampare

[[1, 1, 1], [0, 0, 0]] 

ma esso stampa

[[1, 1, 1], [1, 1, 1]] 

risposta

14

Questo legato alla progettazione. Quando usi la moltiplicazione sugli elementi di una lista, stai riproducendo i riferimenti.

Vedere the section "List creation shortcuts" on the Python Programming/Lists wikibook che entra in dettaglio sui problemi con i riferimenti di elenco agli oggetti mutabili.

La loro soluzione consigliata è una lista di comprensione:

>>> s = [[0]*3 for i in range(2)] 
>>> s 
[[0, 0, 0], [0, 0, 0]] 
>>> s[0][1] = 1 
>>> s 
[[0, 1, 0], [0, 0, 0]] 
6

Questo è un po 'diabolico, ma abbastanza ovvio quando si capisce quello che stai facendo. quando stai facendo il [[0]*3]*2 bit, devi prima creare un elenco con 3 zeri, quindi lo copi per creare due elementi. Ma quando fai quella copia, non crei nuove liste con gli stessi contenuti, ma fai riferimento più volte allo stesso elenco. Quindi quando ne cambi uno, cambiano tutti.

Un esempio per evidenziarlo:

In [49]: s = [[]]*2 # Create two empty lists 

In [50]: s # See: 
Out[50]: [[], []] 

In [51]: s[0].append(2) # Alter the first element (or so we think) 

In [52]: s # OH MY, they both changed! (because they're the same list!) 
Out[52]: [[2], [2]]