2015-12-21 14 views
5

Ich bin alt und habe keine Haare herausziehen gelassen. Ich habe so viele Antworten auf ähnliche Fragen gelesen wie auf SO. Ich habe den folgenden Code:Python 3.5 Liste Verständnis ändert Original

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)` 

Ausgang ist:

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']] 

ich für das Ergebnis bin auf der Suche, wie gezeigt ‚c nach:‘ aber ich verstehe nicht, warum ein geändert, auch ?! Ich habe auch versucht

c = list(a) 

und

c = copy.copy(a) 

Natürlich einfach c = a funktioniert nicht wie erwartet. Was vermisse ich ?! Danke.

Antwort

7

Dies ist, weil Sie nicht die Elemente innerhalb der Liste kopieren. Listen innerhalb von a werden nicht kopiert. Daher wirkt sich Ihre extend Methode auf Elemente in beiden Listen aus. Sie sollten c = copy.deepcopy(a) verwenden, um verschachtelte Elemente zu kopieren.

1

try Zuweisung c Liste wie folgt (ohne .copy() Lösung)

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

oder eine Auskleidung mit Liste Verständnis

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

Diese liefert tiefe Kopie, wenn Sie die Liste in einer Liste haben Natürlich nicht 3 Schichten.

Der Grund, was Sie es versäumt haben, die Sie verwaltete Liste richtig zu kopieren, aber die Listen innerhalb noch denselben Speicherwert refenced zu, daher gab es keine Kopie in Elementlisten. Diese Lösung kopiert auch innerhalb von Listen, die Definition von Deepcopy ist.

0

Wie die anderen Poster erklären, werden die Listen in A nicht wirklich nach C kopiert - sie sind nur Verweise auf die Originale. Sie können sehen, dass, wenn Sie den Code ausführen:

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) 

Welche "True" druckt, was bedeutet, dass die [1,2] innerhalb lists_copy ist eigentlich die [1,2] von num_lists. Das Kopieren von Python-Listen ist viel zu kompliziert und ich hoffe, dass sie es ändern, um in Zukunft freundlicher zu sein. Ab sofort ist das Beste, was Sie tun können: lists_copy = copy.deepcopy(num_lists)

Sie es unten arbeiten sehen:

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) 

Dieser Code druckt „False“ wird die Liste Bedeutung, um sicher kopiert und Balance wird schließlich wiederhergestellt das Universum:)

0

Beachten Sie auch, dass die Listen sind wandelbar Typen, die nach der Erstellung im Gegensatz zu unveränderlichen Typen wie Strings beispielsweise modifiziert werden können. Unveränderliche Typen können nach ihrer Erstellung nicht geändert werden. Daher wird eine echte Kopie einer Zeichenfolge erstellt, wenn Sie versuchen würden, eine zweite Zeichenfolge an sie anzuhängen. Veränderliche Typen können geändert werden. Daher wird keine Kopie erstellt, und sowohl a als auch c verweisen auf dieselbe Liste.