2015-07-25 3 views
7

Ich verstehe die Unterschiede zwischen flachen Kopie und tiefe Kopie, wie ich in der Klasse gelernt habe. in einer tiefen Kopie jedoch nicht die folgenden nicht SinnKopieren und Deepcopy in Python3

import copy 

a = [1, 2, 3, 4, 5] 

b = copy.deepcopy(a) 

print(a is b) 
print(a[0] is b[0]) 
---------------------------- 
~Output~ 
>False 
>True 
---------------------------- 

machen Sollte nicht print(a[0] is b[0]) auf False zu bewerten, da die Objekte und deren Bestandteile an einem anderen Speicherort neu erstellt werden? Ich habe das gerade getestet, da wir das im Unterricht besprochen hatten, aber es scheint nicht zu funktionieren.

Antwort

7

Der Grund für dieses Verhalten ist, dass Python kleine Ganzzahlen optimiert, so dass sie sich nicht an einem anderen Speicherort befinden. Schauen Sie sich die id von 1, sie sind immer die gleichen:

>>> x = 1 
>>> y = 1 
>>> id(x) 
1353557072 
>>> id(y) 
1353557072 

>>> a = [1, 2, 3, 4, 5] 
>>> id(a[0]) 
1353557072 

>>> import copy 
>>> b = copy.deepcopy(a) 
>>> id(b[0]) 
1353557072 

Referenz von Integer Objects:

Die aktuelle Implementierung eine Reihe von Integer-Objekte für alle ganzen Zahlen zwischen -5 und 256 hält, Wenn Sie einen int in diesem Bereich erstellen, erhalten Sie nur einen Verweis auf das vorhandene Objekt zurück. Daher sollte es möglich sein, den Wert 1 zu ändern. Ich vermute, dass das Verhalten von Python in diesem Fall nicht definiert ist. :-)

+0

Ist nicht das, was Sie beschreiben die Principal von "seichten Kopien" dh copy.copy (a), wenn copy.deepcopy (a), sollten die Elemente alle in verschiedenen Speicherorten, dh diese ID (a [0]) ! = id (b [0]) –

+0

@GeraldLee: Dies ist ein spezieller Fall, in dem die 'kleinen' Ganzzahlen ('<257') am Speicherort fixiert werden, um häufige Operationen zu beschleunigen. Versuchen Sie Folgendes: 'a, b = (Liste (Bereich (258)), Liste (Bereich (258))); [id (a [i]) == id (b [i]) für i in Bereich (258)] 'in einer Python-REPL – Steen

+0

Kleine Ints sind Beispiele für Python-Singletons. Andere sind 'None',' True' und 'False' – PMende

0

Die Antwort von Yu Hao ist eigentlich nicht korrekt. Es stimmt, dass Python eindeutige Objekte für kleine ganze Zahlen hat, aber es ist nicht das, was dieses Verhalten verursacht.

Überprüfen Sie, was passiert, wenn Sie größere Ganzzahlen verwenden.

> from copy import deepcopy 
> x = 1000 
> x is deepcopy(x) 
True 

Wenn Sie in der copy Modul Sie herausfinden, graben, wenn Sie deepcopy ein atomarer Wert, den Aufruf einer Funktion aufschiebt _deepcopy_atomic genannt.

def _deepcopy_atomic(x, memo): 
    return x 

Also, was tatsächlich passiert ist, dass deepcopy nicht einen unveränderlichen Wert kopieren, sondern nur zurück.

Die Typen, die zu sein atomics betrachtet werden, schließen int, float, bool, str und vieles mehr.