2013-06-13 3 views
9

Gerade als ich dachte, ich hätte verstanden, wie Python-Listen arbeiten ...Kopieren Python Listen

>>> a = [1,2,3] 
>>> b = a[:] 
>>> b 
[1,2,3] 
>>> b[1]=100 
>>> b 
[1,100,3] 
>>> a 
[1,2,3] 

So weit, so gut. Ich initialisiere b mit dem Inhalt von a, so dass b auf ein anderes Objekt zeigt. Folglich beeinflussen Änderungen in b nicht a.

nun einen Blick auf diese anderen Beispiel nehmen:

>>> a = [[1,2,3],[4,5,6],[7,8,9]] 
>>> b = a[:][:] 
>>> b 
[[1,2,3],[4,5,6],[7,8,9]] 
>>> b[1][1] = 100 
>>> b 
[[1,2,3],[4,100,6],[7,8,9]] 
>>> a 
[[1,2,3],[4,100,6],[7,8,9]] 

Warum hat sich in b die Änderung betroffen ein dieses Mal? Was unterscheidet sich vom vorherigen Beispiel?

+1

Beachten Sie, dass die Verwendung von '[:]' zu kopieren ist ein wenig kryptisch - in der Regel finde ich es viel schöner, 'list()' oder 'copy.copy()' zu verwenden, abhängig vom Kontext. (Natürlich ist, wie in Antworten darauf hingewiesen, 'copy.deepcopy()' möglicherweise das, was Sie hier haben wollen). –

Antwort

11

Der Schneidevorgang x[:] ergibt eine flache Kopie. Das heißt, die äußere Liste ist anders, enthält aber die exakt gleichen Elemente. a = [[1]] annehmen:

b = a[:] # is the same as: 
b = [x for x in a] 

>>> a[0] is b[0] 
True 

Das Doppel Slicing ([:][:]) ist nichts anderes als das zu tun - wieder:

b = a[:][:] # is the same as: 
b = [y for y in [x for x in a]] 

>>> a[0] is b[0] 
True 

Eine flache Kopie einer flachen Kopie ist, na ja, eine flache Kopie.

Also b ist immer noch eine flache Kopie von a - diese Listen sind verschiedene Objekte, aber sie enthalten identische Elemente. Dann mutieren Sie die innere Liste in b, aber es ist die gleiche Liste in a.

2-stufige flache Kopie kann mit b=[x[:] for x in a] durchgeführt werden. Es erstreckt sich auf die gleiche Weise für N-Level-Kopie.

Übrigens hat der Begriff "flache Kopie" die gleiche Bedeutung für jede Klasse oder Container.

Wenn Sie eine echte Tiefenkopie wünschen, sollten Sie die Verwendung von deep copy in Betracht ziehen.

+1

Eine "flache Kopie"! Ich kannte dieses Konzept nicht. Vielleicht können Sie die Antwort leicht bearbeiten, um sie etwas zu erklären (nur ein paar Worte). –

+0

+1 für eine gute Erklärung zusammen mit einer Lösung – Sid

+0

@MarcosGonzalez ist es jetzt besser? – Elazar

4

Die Versilberung [:] erzeugt eine flache Kopie. aber innere Objekte bleiben nicht kopiert, so wenn sie wandelbar sind und Sie werden sie geändert werden sie verändert werden;) und in beiden Listen werden Sie diese

Verwendung Liste Verständnis

b = [i[:] for i in a] 

oder copy.deepcopy (siehe)

import copy 
b = copy.deepcopy(a) 
+0

Vielen Dank für die Hinweise! –

1

Try this:

In [38]: import copy 

In [39]: a = [[1,2,3],[4,5,6],[7,8,9]] 

In [40]: b=copy.deepcopy(a) 

In [41]: b[1][1] = 100 

In [42]: a 
Out[42]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

In [43]: b 
Out[43]: [[1, 2, 3], [4, 100, 6], [7, 8, 9]] 

mehr lesen @http://docs.python.org/2/library/copy.html

+0

Vielen Dank für den Hinweis. –