2012-12-06 15 views
9

Ho un elenco di elenchi, ogni elenco all'interno dell'elenco contiene 5 elementi, come posso modificare i valori degli elementi nell'elenco? Ho provato quanto segue:Python - Come modificare i valori in un elenco di elenchi?

for [itemnumber, ctype, x, y, delay] in execlist: 
     if itemnumber == mynumber: 
      ctype = myctype 
      x = myx 
      y = myy 
      delay = mydelay 

Inizialmente ho avuto una lista di tuple, ma ho capito che posso modificare i valori in una tupla così sono passato a liste, ma ho ancora posso cambiare qualsiasi dei valori. Se stampo ctype, x, y, delay, myctype, myx, myy o mydelay dall'interno del ciclo for, sembra che tutto funzioni, ma se stampo la execlist in seguito, vedo che nulla è cambiato.

+0

Gli oggetti sono unici? O c'è un altro motivo per cui vuoi ripetere l'intera lista, anche dopo che è stata effettuata una sostituzione? –

risposta

12

Il problema è che si sta creando una copia dell'elenco e quindi si modifica la copia. Quello che vuoi fare è modificare l'elenco originale. Prova invece:

for i in range(len(execlist)): 
    if execlist[i][0] == mynumber: 
     execlist[i][1] = myctype 
     execlist[i][2] = myx 
     execlist[i][3] = myy 
     execlist[i][4] = mydelay 
2

È necessario assegnare tramite indici. Diciamo che hai un elenco di elenchi, in cui gli elenchi interni hanno ciascuno 5 elementi come quelli che descrivi. Se si desidera iterare attraverso di loro e modificare il valore del secondo elemento in ogni lista interna, si potrebbe fare qualcosa di simile:

l = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]] 
for i in l: 
    i[1] = "spam" 

print l 
(output) [[0, "spam", 2, 3, 4], [5, "spam", 7, 8, 9], [10, "spam", 12, 13, 14]] 
0

spacchettamento variabile non sembra passare il riferimento, ma copia i valori. Una soluzione potrebbe essere quella di fare in questo modo:

foo = [[1, "gggg"], [3, "zzzz"]] 

for item in foo: 
    item[0] = 2 
    item[1] = "ffff" 

print(foo) 

>>>> [[2, 'ffff'], [2, 'ffff']] 
2

si potrebbe usare enumerate():

for index, sublist in enumerate(execlist): 
    if sublist[0] == mynumber: 
     execlist[index][1] = myctype 
     execlist[index][2] = myx 
     execlist[index][3] = myy 
     execlist[index][4] = mydelay 
     # break 

è possibile rimuovere il # se execlist contiene solo al massimo un elenco secondario il cui primo elemento può essere uguale mynumber; altrimenti, percorrerai inutilmente tutto il resto della lista.

E se lo itemnumbers è in realtà univoco, si potrebbe stare meglio con un dizionario o almeno uno OrderedDict, a seconda di che altro si intende fare con i dati.

0

Non assegnare variabili locali negli elenchi. Nel ciclo

for i in lis: 
    i = 5 

Proprio imposta la variabile i-5 e lascia il contenuto effettivo della lista invariato. Invece, è necessario assegnare direttamente:

for i in range(len(lis)): 
    lis[i] = 5 

Lo stesso vale per gli elenchi di liste, anche se in questo caso la variabile locale non deve essere assegnato in modo da poter utilizzare il for...in costrutto.

for i in listoflists: 
    for i2 in range(len(i)): 
      i[i2] = 5 #sets all items in all lists to 5 
0

Modifica delle variabili assegnate nel for non cambia la lista. Ecco un modo abbastanza leggibile per fare ciò che si vuole:

execlist = [ 
    #itemnumber, ctype, x, y, delay 
    [1, 2, 3, 4, 5], 
    [6, 7, 8, 9, 10], 
    [11, 12, 13, 14, 15], 
] 

mynumber, myctype, myx, myy, mydelay = 6, 100, 101, 102, 104 

for i, sublist in enumerate(execlist): 
    if sublist[0] == mynumber: 
     execlist[i] = [mynumber, myctype, myx, myy, mydelay] 

print execlist 

uscita:

[[1, 2, 3, 4, 5], [6, 100, 101, 102, 104], [11, 12, 13, 14, 15]] 
0

Le variabili iteratore sono copie dell'originale (Python non ha un concetto di un punto di riferimento in quanto tale, anche se le strutture come ad esempio le liste si riferiscono per riferimento).Hai bisogno di fare qualcosa di simile:

for item in execlist: 
    if item[0] == mynumber: 
     item[1] = ctype 
     item[2] = myx 
     item[3] = myy 
     item[4] = mydelay 

item è di per sé una copia troppo, ma si tratta di una copia di un riferimento alla lista annidata originale, in modo che quando si fa riferimento ai suoi elementi all'elenco originale viene aggiornato.

Questo non è conveniente in quanto non si hanno i nomi; forse un dizionario o classe sarebbe una struttura più conveniente.

Problemi correlati