2015-12-21 10 views
5

Sono vecchio e non ho più capelli da estrarre. Ho letto tante risposte a domande simili che riesco a trovare su SO. Ho il seguente codice:Comprensione elenco Python 3.5 modifica originale

a = [[1,2],[3,4],[4,5]] 
b = ['a','b','c'] 
print('a:',a) 
print('b:',b) 
c = a[:] 
print('c == a:', c==a) 
print('c is a:',c is a) 
print('id(c) = id(a):', id(c)==id(a)) 
[x.extend(b) for x in c] 
print('c after:',c) 
print('a after:',a)` 

uscita è:

a: [[1, 2], [3, 4], [4, 5]] 
b: ['a', 'b', 'c'] 
c == a: True 
c is a: False 
id(c) = id(a): False 
c after: [[1, 2, 'a', 'b', 'c'], [3, 4, 'a', 'b', 'c'], [4, 5, 'a', 'b', 'c']] 
a after: [[1, 2, 'a', 'b', 'c'], [3, 4, 'a', 'b', 'c'], [4, 5, 'a', 'b', 'c']] 

Sto cercando il risultato mostrato come 'C dopo:' ma non capisco il motivo per cui una viene modificato, troppo ?! Ho anche provato

c = list(a) 

e

c = copy.copy(a) 

Naturalmente, semplice c = a non funziona come previsto. Cosa mi manca ?! Grazie.

risposta

7

Questo perché non si copiano gli elementi all'interno dell'elenco. Gli elenchi all'interno di a non vengono copiati. Pertanto il tuo metodo extend riguarda gli elementi all'interno di entrambi gli elenchi. Dovresti usare c = copy.deepcopy(a) per copiare elementi nidificati.

1

Provate ad assegnare lista c come questo, (senza .copy() soluzione)

c = [] 
for elem in a: 
    c.append(list(elem)) 

o uno di linea con la lista di comprensione

c = [list(elem) for elem in a] 

Questo fornisce copia completa se si dispone di lista all'interno di una lista , non 3 strati, naturalmente.

Il motivo per cui si è riusciti a fallire è che si è riusciti a copiare correttamente l'elenco ma gli elenchi interni hanno ancora lo stesso valore di memoria, quindi non c'era alcuna copia negli elenchi di elementi. Questa soluzione copia anche gli elenchi interni, , che è la definizione di deepcopy.

0

Come gli altri poster hanno spiegato, le liste all'interno di A non sono effettivamente copiate in C - sono solo riferimenti a quelle originali. Si può vedere che quando si esegue il codice qui sotto:

num_lists = [[1,2],[3,4],[4,5]] 
lists_copy = num_lists[:] 

orig_first = num_lists[0] 
copy_first = lists_copy[0] 

print('Are the first elements the same object?', orig_first is copy_first) 

che stampa "True", il che significa che il [1,2] all'interno lists_copy è in realtà la [1,2] da num_lists. Copiare le liste di Python è troppo complicato e spero che cambino per renderle più amichevoli in futuro. A partire da ora, il meglio che puoi fare è: lists_copy = copy.deepcopy(num_lists)

Si può vedere il lavoro di seguito:

from copy import deepcopy 

lists_copy = deepcopy(num_lists) 

orig_first = num_lists[0] 
copy_first = lists_copy[0] 

print('Are they they the same after copying with deepcopy?', orig_first is copy_first) 

stampe di questo codice "False", cioè la lista è in modo sicuro copiato e l'equilibrio è finalmente ripristinato l'universo:)

0

Considera anche che gli elenchi sono tipi modificabili che possono essere modificati dopo la creazione in contrasto con tipi immutabili come le stringhe, ad esempio. I tipi immutabili non possono essere modificati dopo la loro creazione. Pertanto, viene eseguita una copia reale di una stringa se si tenta di aggiungere una seconda stringa ad essa. I tipi mutabili possono essere cambiati. Quindi, non viene effettuata alcuna copia e sia a che c fanno riferimento alla stessa lista.