2016-07-20 7 views
1

Wenn ich eine Liste von Objekten, die als solche in Python:Fügt ein Listen-Slice an die ursprüngliche Liste an, kopieren Sie einfach die Adressen?

li = [obj1, obj2, obj3, ob4, obj5] 

Und ich hängen Sie die letzten beiden Objekte an das Ende der Liste wieder:

li.extend(li[-2:]) 

Sie Duplikate in li jetzt haben die gleiche oder verschiedene Adressen? Wenn ich Änderungen an einem der Elemente des Arrays, das an das Ende der Liste li angehängt wurde, mache, ändert sich auch das Duplikat am Ende? Gibt es eine bessere Möglichkeit, diese Kopie zu erstellen?

Antwort

3

Die gleichen Adressen - Sie können dies mit id überprüfen. Wenn die Elemente der Liste änderbar sind, ändert das Ändern der anderen die andere. Wenn die Elemente der Liste unveränderlich sind, können Sie sie nicht ändern.

li = [1, 1.0, None, ['a', 'b'], ('c', 'd')] 

li.extend(li[-2:]) 
print(li) 
# outputs [1, 1.0, None, ['a', 'b'], ('c', 'd'), ['a', 'b'], ('c', 'd')] 

li[-2].pop() 
print(li) 
# outputs [1, 1.0, None, ['a'], ('c', 'd'), ['a'], ('c', 'd')] 
# Note that elemnts at indices -2 and -4 have changed since id(li[-2]) == id(li[-4]) 

print(id(li[-1]) == id(li[-3])) 
# True 

tiefe Kopien hinzuzufügen, können Sie die copy module verwenden können.

li = [1, 1.0, None, ['a', 'b'], ('c', 'd')] 

li.extend(list(map(copy.deepcopy, li[-2:]))) 
print(li) 
# outputs [1, 1.0, None, ['a', 'b'], ('c', 'd'), ['a', 'b'], ('c', 'd')] 

li[-2].pop() 
print(li) 
# outputs [1, 1.0, None, ['a', 'b'], ('c', 'd'), ['a'], ('c', 'd')] 
# Note that only the list at index -2 has changed since id(li[-2]) != id(li[-4]) 

Beachten Sie, dass für unveränderliche Objekte, copy.deepcopy keine Kopie des Objekts machen, es sei denn, dass Objektverweise auf andere veränderbare Objekte hat. Also in der letzten Liste id(li[-1]) == id(li[-3]).

+0

Ein anderer Teil meiner Frage ist: "Gibt es eine Möglichkeit, dies zu tun, so dass eine echte Kopie gemacht wird?" – jackskis

+1

@jackskis aktualisiert – Alex

+0

Vielen Dank! – jackskis

1

Ja, Python wird Referenz das gleiche Objekt im Speicher, wenn Sie die extend() Methode auf diese Weise verwenden, wenn dies Ihr gewünschtes Ergebnis ist, führen Sie dann einfach:

li.extend(li[-2:]) 

Beispiel:

a = object() 
b = object() 
c = object() 
d = object() 
# Alternatively a, b, c, d = object(), object(), object(), object() 
li = [a, b, c, d] 

Nun überprüfen wir unsere Liste li out:

[<object object at 0x7fb84a31e0b0>, 
<object object at 0x7fb84a31e0c0>, 
<object object at 0x7fb84a31e0d0>, # c 
<object object at 0x7fb84a31e0e0>] # d 

Ausführen der Operation auf li, Hinweis die Speicheradresse:

[<object object at 0x7fb84a31e0b0>, 
<object object at 0x7fb84a31e0c0>, 
<object object at 0x7fb84a31e0d0>, 
<object object at 0x7fb84a31e0e0>, 
<object object at 0x7fb84a31e0d0>, # <- Same object as c 
<object object at 0x7fb84a31e0e0>] # <- Same object as d 

Sie werden bemerken, dass die letzten beiden Elemente, die in der Tat die gleich angefügt wurden Objekte im Speicher als das, was die Variablen c und d sind zugewiesen. Das bedeutet, dass Änderungen an den letzten beiden Objekte in der Liste machen auch die Objekte im Index ändern 2 und 3.

Nun, wenn Sie Kopie des von den letzten beiden Elemente hinzufügen wollte, Sie folgendes tun können:

extend_elements = [copy.deepcopy(i) for i in li[-2:]] 
li.extend(extend_elements) 

Für Kopiervorgänge siehe Python's copy module doc.