2013-12-04 8 views
0

Итак, я играю с Python, пытаясь научиться его использовать, и я обнаружил что-то странное. Мой код:Python: поведение странного списка

list1 = range(0, 2) 
list2 = range(2, 4) 

comb = list1, list2 

print comb 
print list1 

list1.append(list2) 

print comb 
print list1 

выходы:

print comb --- ([0, 1], [2, 3]) 
print list1 --- [0, 1] 

print comb --- ([0, 1, [2, 3]], [2, 3]) 
print list1 --- [0, 1, [2, 3]] 

Что, кажется, происходит это я комбинируя мои два списка, который работает отлично. Но когда я добавлю list2 в list1 и перепечатаю список comb, список comb был обновлен недавно добавленным list1.

Что мне не хватает? Почему comb изменяется, если он не был пересчитан с момента добавления list1?

ответ

2

comb содержит ссылки на list1 и list2 сами, а не их копии. Кроме того, это означает, что comb[0] фактически является list1 и вице-верой.

Ниже демонстрация:

>>> list1 = range(0, 2) 
>>> list2 = range(2, 4) 
>>> comb = list1, list2 
>>> id(list1) 
28888960 
>>> id(comb[0]) 
28888960 
>>> 

В приведенном выше примере, обратите внимание, как идентификаторы list1 и comb[0] одинаковы. Это говорит о том, что оба они ссылаются на один и тот же объект в памяти. Таким образом, когда вы обновляете один, другой будет также обновляться.


Чтобы устранить эту проблему, сделать comb содержат копии из list1 и list2 вместо ссылок:

>>> list1 = range(0, 2) 
>>> list2 = range(2, 4) 
>>> # [:] creates a shallow copy of the lists. 
>>> comb = list1[:], list2[:] 
>>> id(list1) 
28930176 
>>> id(comb[0]) 
28931696 
>>> 

Как вы можете видеть, идентификаторы list1 и comb[0] которые теперь отличаются. Это означает, что они больше не ссылаются на один и тот же объект.

0

comb содержит ссылки - list1 и list2. Таким образом, при обновлении list1 обновляется comb.

Если вы хотите comb держать копию данных из list1 и list2 вместо ссылки, попробуйте:

comb = (list1[:], list2[:]) 
2

comb является кортежем, с двумя ссылки в том же списке объектов, что list1 и list2 названия относятся к.

Когда вы добавили list2 на номер list1, вы добавили другую ссылку на этот список в list1. Теперь у вас есть ссылки на этот объект списка. Один в list2, другой в comb[1] и третий в list1[2].

Всякий раз, когда вы манипулируете списком или словарем или любым другим изменяемым типом объектов в Python, все ссылки на этот объект будут отражать эти изменения, поскольку вы имеете дело только с одним объектом.

Изобразительные объекты как воздушные шары, а также имена - это метки, привязанные к воздушным шарам с резьбой. Нити - это ссылки. Вы можете привязать несколько ярлыков к воздушному шару, но у вас все равно будет только один один воздушный шар, и если вы выскочите шар, все ярлыки будут привязаны к тому же куску безжизненной резины.

Списки и кортежи - это просто воздушные шары с пронумерованными этикетками, наклеенными на них; эти метки привязаны к другим объектам. Таким образом, comb представляет собой воздушный шар с двумя наклеенными этикетками, пронумерованными 0 и 1. Эти ярлыки привязаны к тем же воздушным шарам list1 и list2 привязаны к , а также.

0

comb состоит из list1 и list2. Мутирование list1 не меняет этого, и кажется, что в действительности comb изменилось, в то время как в действительности это все равно.

0

У меня был мой коллега на днях. Этот эффект связан с ваших

comb = list1, list2 

Вы должны использовать

comb = list(list1 + list2) 

на самом деле скопировать список, см http://www.precheur.org/python/copy_list и http://od-eon.com/blogs/bogdan/python-assignment-value-or-reference/

+0

comb = list (list1 + list2) – user3067926

+0

Спасибо! Я исправил опечатку. – fuesika

Смежные вопросы