2012-10-31 17 views
18

Non esiste alcun tipo di array in python, ma per emularlo possiamo usare le liste. Voglio avere una struttura di tipo 2d riempita con zero. La mia domanda è: qual è la differenza, se del caso, in questo due espressioni:2d array di zeri

zeros = [[0 for i in xrange(M)] for j in xrange(M)] 

e

zeros = [[0]*M]*N 

Sarà zeros essere lo stesso? quale è meglio usare per mezzo di velocità e leggibilità?

risposta

28

È necessario utilizzare numpy.zeros. Se questa non è un'opzione, vuoi la prima versione. Nella seconda versione, se si cambia un valore, esso sarà cambiato altrove nella lista - ad esempio:

>>> a = [[0]*10]*10 
>>> a 
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 
>>> a[0][0] = 1 
>>> a 
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

Questo perché (come si legge l'espressione dall'interno verso l'esterno), si crea un elenco di 10 zeri. Quindi si crea un elenco di 10 riferimenti a quell'elenco iniziale di 10 zeri.


Nota che:

zeros = [ [0]*M for _ in xrange(N) ] 

lavorerà anche ed evita la lista di comprensione nidificato. Se numpy non è sul tavolo, questo è il modulo che userei.

+0

È proprio necessario utilizzare NumPy semplicemente per quella singola caratteristica? +1 per la prima versione. – John

+1

@johnthexiii - Forse no. Ma, se l'OP vuole un array di zeri 2d, sarei disposto ad andare su un arto e dire che il codice OP potrebbe probabilmente trarre beneficio da Numpy anche in altri posti. – mgilson

+0

non installerò numpy solo per azzerare la lista;) Grazie per la spiegazione successiva, era quello che stavo cercando. – yakxxx

2

Nel secondo caso si crea un elenco di riferimenti alla stessa lista. Se hai un codice del tipo: [lst] * N dove lst è un riferimento a un elenco, avrai il seguente elenco: [Ist, Ist, Ist, Ist, ..., Ist]. Ma poiché l'elenco dei risultati contiene riferimenti allo stesso oggetto, se si modifica il valore in una riga verrà modificato in tutte le altre righe.

7

per Python 3 (senza più xrange), la risposta

zeros = [ [0] * N for _ in range(M)] 

preferito per M x N matrice di zeri