2016-07-20 95 views
1

如果我有對象作爲這樣的一個Python列表:是否將列表切片追加到原始列表中只複製地址?

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

我最後兩個對象再次追加到列表的末尾:

li.extend(li[-2:]) 

不要在li重複現在有相同或不同的地址?如果我修改了列表li末尾附加的數組元素之一,那麼最後的副本是否也會改變?如果有的話,是否有更好的方法來預製此副本?

回答

3

相同的地址 - 你可以用id進行檢查。如果列表中的元素是可變的,那麼修改一個會修改另一個。如果列表的元素是不可變的,那麼你不能修改它們。

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 

要添加深拷貝,您可以使用copy module

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

注意,對於不可變對象,copy.deepcopy不會使對象的副本除非對象具有其他可變對象的引用。所以在最後的名單id(li[-1]) == id(li[-3])

+0

我的問題的另一部分是:「有沒有辦法做到這一點,使得真正的副本製作? – jackskis

+1

@jackskis更新 – Alex

+0

非常感謝! – jackskis

1

是,蟒蛇將參考內存中的同一個對象,如果你使用extend()方法以這種方式,如果這是你想要的結果,那麼只需執行:

li.extend(li[-2:]) 

例子:

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

現在我們看看我們的名單li

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

運行您的li操作,通知的內存地址:

[<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 

你會發現,被附加了最後兩個元素確實是相同對象在內存中的變量是什麼cd被分配給。這意味着,在更改列表中的最後兩個對象也將改變對象的索引2 3.

現在,如果你想添加的最後兩個元素的副本的,你可以做到以下幾點:

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

複製操作請參考Python's copy module doc