Crea un elenco vuoto in Python con determinate dimensioni


546

Voglio creare un elenco vuoto (o qualunque sia il modo migliore) che può contenere 10 elementi.

Dopodiché voglio assegnare valori in quell'elenco, ad esempio questo dovrebbe visualizzare da 0 a 9:

s1 = list();
for i in range(0,9):
   s1[i] = i

print  s1

Ma quando eseguo questo codice, genera un errore o in un altro caso viene visualizzato [](vuoto).

Qualcuno può spiegare perché?



7
Un "elenco vuoto" ( []) per definizione ha zero elementi. Quello che a quanto pare vuole è un elenco di valori falsy come None, 0, o ''.
dan04

Per generare un elenco da 0a 9si dovrebbe effettivamente utilizzare for i in range(0, 10), quali mezzi for (int i = 0, i < 10, i++).
Atcold,

Risposte:


833

Non è possibile assegnare a un elenco come lst[i] = something, a meno che l'elenco non sia già inizializzato con almeno i+1elementi. È necessario utilizzare append per aggiungere elementi alla fine dell'elenco. lst.append(something).

(È possibile utilizzare la notazione di assegnazione se si utilizza un dizionario).

Creazione di un elenco vuoto:

>>> l = [None] * 10
>>> l
[None, None, None, None, None, None, None, None, None, None]

Assegnare un valore a un elemento esistente dell'elenco sopra:

>>> l[1] = 5
>>> l
[None, 5, None, None, None, None, None, None, None, None]

Tieni presente che qualcosa del genere l[15] = 5fallirebbe ancora, poiché la nostra lista ha solo 10 elementi.

range (x) crea un elenco da [0, 1, 2, ... x-1]

# 2.X only. Use list(range(10)) in 3.X.
>>> l = range(10)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Utilizzo di una funzione per creare un elenco:

>>> def display():
...     s1 = []
...     for i in range(9): # This is just to tell you how to create a list.
...         s1.append(i)
...     return s1
... 
>>> print display()
[0, 1, 2, 3, 4, 5, 6, 7, 8]

Comprensione della lista (Usando i quadrati perché per l'intervallo non è necessario fare tutto questo, puoi semplicemente tornare range(0,9)):

>>> def display():
...     return [x**2 for x in range(9)]
... 
>>> print display()
[0, 1, 4, 9, 16, 25, 36, 49, 64]

17
Cosa intendi con "Non puoi assegnare a un elenco come lst [i] = qualcosa" - certo che puoi! Quello che non puoi fare è assegnare ad un elemento inesistente oltre l'attuale lunghezza della lista
Sergey,

5
"a meno che l'elenco non sia già inizializzato con almeno i + 1 elementi" ....
MrR

5
puoi farlo:a = [0 for _ in range(10)]
Kamiar il

È possibile farlo utilizzando la funzione list ()?
Raul Chiarella,

126

Prova questo invece:

lst = [None] * 10

Quanto sopra creerà un elenco di dimensioni 10, in cui ogni posizione è inizializzata None. Successivamente, è possibile aggiungere elementi ad esso:

lst = [None] * 10
for i in range(10):
    lst[i] = i

Certo, questo non è il modo Pythonic di fare le cose. Meglio farlo:

lst = []
for i in range(10):
    lst.append(i)

O ancora più semplice , in Python 2.x puoi farlo per inizializzare un elenco con valori da 0 a 9:

lst = range(10)

E in Python 3.x:

lst = list(range(10))

2
L'altro aspetto interessante è che puoi inizializzare un elenco con valori predefiniti. lst = [''] * 10oppurelst = [0] * 10
Anthony Manning-Franklin,

2
Una variante dell'esempio di comprensione. Se tutti gli elementi della matrice necessità di essere vuoto all'inizializzazione, utilizzare: arr = [None for _ in range(10)].
Doug R.

86

la risposta attualmente accettata da varunl

 >>> l = [None] * 10
 >>> l
 [None, None, None, None, None, None, None, None, None, None]

Funziona bene per tipi non di riferimento come numeri. Sfortunatamente, se si desidera creare un elenco di elenchi, si verificheranno errori di riferimento. Esempio in Python 2.7.6:

>>> a = [[]]*10
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> 

Come puoi vedere, ogni elemento punta allo stesso oggetto elenco. Per ovviare a questo, è possibile creare un metodo che inizializzerà ciascuna posizione su un riferimento oggetto diverso.

def init_list_of_objects(size):
    list_of_objects = list()
    for i in range(0,size):
        list_of_objects.append( list() ) #different object reference each time
    return list_of_objects


>>> a = init_list_of_objects(10)
>>> a
[[], [], [], [], [], [], [], [], [], []]
>>> a[0].append(0)
>>> a
[[0], [], [], [], [], [], [], [], [], []]
>>> 

Esiste probabilmente un modo predefinito e incorporato di pitone per farlo (invece di scrivere una funzione), ma non sono sicuro di cosa si tratti. Sarebbe felice di essere corretto!

Modifica: lo è [ [] for _ in range(10)]

Esempio :

>>> [ [random.random() for _ in range(2) ] for _ in range(5)]
>>> [[0.7528051908943816, 0.4325669600055032], [0.510983236521753, 0.7789949902294716], [0.09475179523690558, 0.30216475640534635], [0.3996890132468158, 0.6374322093017013], [0.3374204010027543, 0.4514925173253973]]

19
Ho sentito che usare appendmolto spesso è inferiore per elencare le comprensioni. Puoi creare il tuo elenco di elenchi tramite [ [] for _ in range(10)].
M.Herzkamp,

10
È stato votato perché mi stavo arrabbiando perché avevo un array multidimensionale con gli stessi dati ripetuti più volte e non riuscivo a capire cosa stesse succedendo prima di trovare finalmente questa risposta. ^^ Non capisco perché sia ​​così basso qui.
Bregalad,

19

È possibile .append(element)a elenco, ad esempio: s1.append(i). Quello che stai attualmente cercando di fare è accedere a un elemento ( s1[i]) che non esiste.


16

Esistono due metodi "rapidi":

x = length_of_your_list
a = [None]*x
# or
a = [None for _ in xrange(x)]

Sembra che [None]*xsia più veloce:

>>> from timeit import timeit
>>> timeit("[None]*100",number=10000)
0.023542165756225586
>>> timeit("[None for _ in xrange(100)]",number=10000)
0.07616496086120605

Ma se stai bene con un intervallo (ad esempio [0,1,2,3,...,x-1]), allora range(x)potrebbe essere il più veloce:

>>> timeit("range(100)",number=10000)
0.012513160705566406

Nota che in Python3 dovrai list(range(n))invece usare , poiché range()non restituisce un elenco ma è un iteratore e non è più veloce di [None] * n.
Skillmon piace topanswers.xyz il

10

Sono sorpreso che nessuno suggerisca questo semplice approccio alla creazione di un elenco di elenchi vuoti. Questo è un vecchio thread, ma è sufficiente aggiungerlo per completezza. Questo creerà un elenco di 10 elenchi vuoti

x = [[] for i in range(10)]

7
La differenza più importante tra fare quanto sopra e fare x = [[]] * 10è che in quest'ultimo, ogni elemento nell'elenco punta all'oggetto elenco SAME . Quindi, a meno che non si desideri semplicemente 10 copie dello stesso oggetto, utilizzare la rangevariante di base in quanto crea 10 nuovi oggetti. Ho trovato questa distinzione molto importante.
Mandeep Sandhu,

6

(Questo è stato scritto in base alla versione originale della domanda.)

Voglio creare un elenco vuoto (o qualunque sia il modo migliore) può contenere 10 elementi.

Tutti gli elenchi possono contenere tutti gli elementi che desideri, soggetti solo al limite della memoria disponibile. L'unica "dimensione" di un elenco che conta è il numero di elementi attualmente presenti in esso.

ma quando lo eseguo, il risultato è []

print display s1non è una sintassi valida; in base alla tua descrizione di ciò che stai vedendo, presumo che tu intendessi display(s1)e quindi print s1. Affinché ciò avvenga, è necessario aver precedentemente definito un globale s1per passare alla funzione.

La chiamata displaynon modifica l'elenco passato, come scritto. Il tuo codice dice " s1è un nome per qualunque cosa sia stata passata alla funzione; ok, ora la prima cosa che faremo è dimenticare completamente quella cosa, e s1cominciamo a fare riferimento invece a una nuova creazione list. Ora lo modificheremo list". Questo non ha alcun effetto sul valore che hai passato.

Non c'è motivo di passare un valore qui. (Non c'è alcun motivo reale per creare una funzione, ma questo è a parte il punto.) Volete "creare" qualcosa, in modo che sia l'output della vostra funzione. Non sono necessarie informazioni per creare ciò che descrivi, quindi non passare alcuna informazione. Per ottenere informazioni, returnè necessario.

Questo ti darebbe qualcosa del tipo:

def display():
    s1 = list();
    for i in range(0, 9):
        s1[i] = i
    return s1

Il prossimo problema che noterai è che il tuo elenco in realtà avrà solo 9 elementi, poiché il punto finale viene ignorato dalla rangefunzione. (Come note a margine, []funziona altrettanto bene list(), anche il punto e virgola non è necessario, s1è un nome mediocre per la variabile, e solo un parametro è necessario rangese si parte da 0.) Quindi si finisce con

def create_list():
    result = list()
    for i in range(10):
        result[i] = i
    return result

Tuttavia, questo manca ancora il segno; rangenon è una parola chiave magica che fa parte del linguaggio in questo modo fore lo defsono, ma invece è una funzione. E indovina cosa restituisce quella funzione? Esatto: un elenco di questi numeri interi. Quindi l'intera funzione crolla a

def create_list():
    return range(10)

e ora capisci perché non abbiamo bisogno di scrivere una funzione da soli; rangeè già la funzione che stiamo cercando. Anche se, ancora una volta, non c'è bisogno o motivo di "ridimensionare" l'elenco.


4

Un modo semplice per creare una matrice 2D di dimensioni nutilizzando la comprensione di elenchi nidificati:

m = [[None for _ in range(n)] for _ in range(n)]

3

Sono un po 'sorpreso che il modo più semplice per creare un elenco inizializzato non sia in nessuna di queste risposte. Basta usare un generatore nella listfunzione:

list(range(9))

1
Un po 'curioso del motivo per cui qualcuno ancora commenta questo ... Sono un pitone e io questo sembra la strada da percorrere, ma nessuno dice niente. Forse la funzione di portata potrebbe essere costosa o qualcosa del genere?
AFP_555,

3
Questo problema è che questa risposta non crea un elenco vuoto come da domanda, finirai con [0, 1, 2, 3, 4, 5, 6, 7, 8] che è ciò che fa la funzione range (9) . Supporre un'istanza di un elenco di Nones è utile piuttosto che riempirlo subito con numeri
Spcogg il secondo

Perché avvolgere il range(9)in list()? Non range(9)restituisce già un elenco?
Zyl,

2
@Zyl rangenon è un elenco, né un generatore. È una sottoclasse immutabile incorporata di Sequence.
Nuno André,

1
@ AFP_555 Penso che la vera domanda sia perché non viene più sottoposta a downgrade, in quanto non risponde realmente alla domanda e potrebbe avere conseguenze indesiderate.
eric,

1

Ecco il mio codice per la lista 2D in Python che avrebbe letto no. di righe dall'input:

empty = []
row = int(input())

for i in range(row):
    temp = list(map(int, input().split()))
    empty.append(temp)

for i in empty:
    for j in i:
        print(j, end=' ')
    print('')

0

La risposta accettata ha alcuni gotchas. Per esempio:

>>> a = [{}] * 3
>>> a
[{}, {}, {}]
>>> a[0]['hello'] = 5
>>> a
[{'hello': 5}, {'hello': 5}, {'hello': 5}]
>>> 

Quindi ogni dizionario si riferisce allo stesso oggetto. Lo stesso vale se si esegue l'inizializzazione con matrici o oggetti.

Invece potresti farlo:

>>> b = [{} for i in range(0, 3)]
>>> b
[{}, {}, {}]
>>> b[0]['hello'] = 6
>>> b
[{'hello': 6}, {}, {}]
>>> 

-2

Mi sono imbattuto in questa domanda SO durante la ricerca di un problema simile. Ho dovuto costruire un array 2D e quindi sostituire alcuni elementi di ciascun elenco (in array 2D) con elementi di un dict. Mi sono poi imbattuto in questa domanda SO che mi ha aiutato, forse questo aiuterà gli altri principianti a muoversi. Il trucco chiave era inizializzare l'array 2D come un array intorpidito e quindi utilizzare array[i,j]invece di array[i][j].

Per riferimento questo è il pezzo di codice in cui ho dovuto usare questo:

nd_array = []
for i in range(30):
    nd_array.append(np.zeros(shape = (32,1)))
new_array = []
for i in range(len(lines)):
    new_array.append(nd_array)
new_array = np.asarray(new_array)
for i in range(len(lines)):
    splits = lines[i].split(' ')
    for j in range(len(splits)):
        #print(new_array[i][j])
        new_array[i,j] = final_embeddings[dictionary[str(splits[j])]-1].reshape(32,1)

Ora so che possiamo usare la comprensione dell'elenco, ma per semplicità sto usando un ciclo nidificato. Spero che questo aiuti gli altri che si imbattono in questo post.


-2

Renderlo più riutilizzabile come funzione.

def createEmptyList(length,fill=None):
    '''
    return a (empty) list of a given length
    Example:
        print createEmptyList(3,-1)
        >> [-1, -1, -1]
        print createEmptyList(4)
        >> [None, None, None, None]
    '''
    return [fill] * length

-3
s1 = []
for i in range(11):
   s1.append(i)

print s1

Per creare un elenco, basta usare queste parentesi: "[]"

Per aggiungere qualcosa a un elenco, utilizzare list.append ()


-3

Questo codice genera un array che contiene 10 numeri casuali.

import random
numrand=[]
for i in range(0,10):
   a = random.randint(1,50)
   numrand.append(a)
   print(a,i)
print(numrand)

3
Benvenuti in SO. La tua risposta non risponde in modo specifico alla domanda. Dai un'occhiata a stackoverflow.com/help/how-to-answer
Nick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.