2010-09-07 15 views
10

C'è un modo in Python per inizializzare un array/elenco multidimensionale senza utilizzare un ciclo?Inizializzazione array multidimensionale Python senza loop

+0

Questa domanda è leggermente vaga: si desidera inizializzare un array multidimensionale vuoto o si desidera inizializzare l'array multidimensionale su un insieme specifico di valori? –

risposta

12

Sicuro ci sono è un modo

arr = eval(`[[0]*5]*10`) 
.210

o

arr = eval(("[[0]*5]+"*10)[:-1]) 

ma è orribile e uno spreco, così tutti usano i loop (di solito di lista) o NumPy

+0

Contrassegnarlo come meglio risponde alla domanda. numpy non fa parte dell'installazione standard di Python. – Leonid

+1

Questo ha lo svantaggio di creare riferimenti agli stessi oggetti, vedere [questa risposta] (http://stackoverflow.com/a/3662548/393885) –

+1

@black_puppydog, no non lo fa. Ecco perché qui viene usato eval qui –

2

Dipende da cosa si intende inizializzare l'array, ma sicuro. È possibile utilizzare un elenco di comprensione per creare un array di 5 × 3, per esempio:

>>> [[0 for x in range(3)] for y in range(5)] 
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] 

>>> [[3*y+x for x in range(3)] for y in range(5)] 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14]] 

Sì, suppongo che questo ha ancora loop — ma è tutto fatto in una linea, che presumo è il significato inteso del vostro domanda?

+3

Che non conta come usare un loop? –

+0

I documenti lo specificano come modo per inizializzare l'elenco multidimensionale. Per una lista di una dimensione è possibile la seguente inizializzazione 'list = [5] * 10', ma non è possibile farla funzionare con più dimensioni. Sembra che quando si esegue 'list = [[5] * 5] * 5', ciascuna sottodimensione punta alla stessa memoria, che non è ciò che voglio. – Leonid

5

Certo, si può solo fare

mylist = [ 
      [1,2,3], 
      [4,5,6], 
      [7,8,9] 
     ] 
+3

Hai perfettamente ragione e non ti sto chiedendo come sarà la matrice 1000 X 1000 ... – Leonid

9

A seconda delle esigenze reali, de facto "standard" pacchetto Numpy potrebbe fornire esattamente ciò che serve.

È possibile ad esempio creare una matrice multidimensionale con

numpy.empty((10, 4, 100)) # 3D array 

(inizializzati con valori arbitrari) o creare le stesse matrici con zeri dappertutto con

numpy.zeros((10, 4, 100)) 

Numpy è molto veloce, per operazioni su array.

+0

Hm ... entrambi questi esempi creano un array 10 x 4 x 100? –

+1

Lo fanno sicuramente. Puoi controllare questo facendo 'a = numpy.empty ((10, 4, 100)); stampa a.shape'. – EOL

3

Non credo sia possibile.

si può fare qualcosa di simile:

>>> a = [[0] * 5] * 5 

per creare una matrice 5x5, ma viene ripetuto gli oggetti (che non si vuole). Per esempio:

>>> a[1][2] = 1 
[[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]] 

È quasi certamente necessario utilizzare un certo tipo di ciclo analogo a:

[[0 for y in range(5)] for x in range(5)] 
+1

>>> a = [[0] * 5] * 5 È un po 'pericoloso. Forse è buono se usi zero. Ma se provi a mettere la tua variabile lì. Ottieni un elenco di elenchi che fa riferimento allo stesso valore. per esempio quando imposti un [1] [1] = 5 - tutta la lista avrà l'elemento in 1 posizione come 5! – RredCat

1

Se stai facendo il lavoro numerica utilizzando Numpy, qualcosa come

x = numpy.zeros ((m,n)) 
x = numpy.ones ((m,n)) 
3

ricorsione è tuo amico: D

Si tratta di un'implementazione abbastanza ingenua ma funziona !

dim = [2, 2, 2] 

def get_array(level, dimension): 
    if(level != len(dimension)): 
     return [get_array(level+1, dimension) for i in range(dimension[level])] 
    else: 
     return 0 

print get_array(0, dim) 
+0

Questo è proprio quello che cercavo, grazie!La mia unica avvertenza è che preferisco mandare giù un array di dimensioni abbreviato, invece di due parametri, come in: [get_array (dimensione [1:]) per j in xrange (dimensione [0])] – Jaime

1

Python non ha array. Ha altri tipi di sequenza che vanno dalle liste ai dizionari senza dimenticare gli insiemi - quello giusto dipende dalle esigenze specifiche.

Assumendo che il "allineamento" è in realtà una lista, e "inizializzare" significa allocare una lista di liste di NxM elementi, è possibile (pseudocodice):

  • per N volte: per M volte: aggiungere un elemento
  • per N volte: aggiungere una riga di elementi M
  • scrivere l'intera cosa fuori

Tu dici che non vuoi loop e che esclude l'abete st due punti, ma perché? Hai anche detto che non vuoi scrivere la cosa (in risposta a JacobM), quindi come faresti esattamente? Non conosco altri modi per ottenere una struttura dati senza generarla in parti più piccole (looping) o scriverla esplicitamente in qualsiasi linguaggio di programmazione.

Inoltre, tenere presente che un elenco inizializzato ma vuoto non è migliore di nessun elenco, a meno che non si inseriscano dati in esso. E non è necessario inizializzarlo prima di inserire dati ...

Se questo non è un esercizio teorico, probabilmente stai facendo la domanda sbagliata. Ti suggerisco di spiegare cosa devi fare con quella matrice.

+0

Hai intenzione di approfondire alcuni dei punti :)) Il punto della domanda è molto semplice e si chiede cosa chiede. Mi stavo chiedendo su tecniche diverse che le persone usano per l'inizializzazione di liste ** multidimensionali **, e le risposte alla domanda riflettono perfettamente ciò che volevo sapere. Alcune persone usano * di fatto la libreria Numpy standard. Alcune persone inizializzano gli elenchi usando ovviamente i cicli 'for'. Come * JacobM * suggerisce che è possibile inizializzare staticamente gli elenchi, ma faccio notare che non è applicabile per elenchi di grandi dimensioni. * gnibbler * suggerisce un modo molto interessante ma funky e non efficiente. – Leonid

+0

Mi stavo particolarmente chiedendo di inizializzare senza 'for' loops, dato che era già ovvio dai documenti come si farebbe con quello. – Leonid

1
a = [[]] 
a.append([1,2]) 
a.append([2,3]) 

Poi

>>> a 
[[1, 2], [2, 3]] 
3

Quanto segue non utilizzare alcun biblioteca speciale, nè eval:

arr = [[0]*5 for x in range(6)] 

e non crea i riferimenti duplicati:

>>> arr[1][1] = 2 
>>> arr 
[[0, 0, 0, 0, 0], 
[0, 2, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]] 
Problemi correlati