2016-08-26 4 views
6

Вот пример:Python: Когда две переменные указывают на один и тот же объект в памяти?

l = [1, 5, 9, 3] 
h = l 

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

h = h*2 
print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

Моего понимание было, что вызов установка h = l бы просто указать h в том же пункте в памяти, что l указывали на. Так почему же в последних 3 строках, h и l не дают одинаковых результатов?

+1

Вы изменяете то, что указывает 'h', когда вы снова назначаете' h'. – user2357112

+0

Это зависит от того, изменено ли значение переменной. Списки являются изменяемыми, целые - нет. –

+0

Установка 'h = l' указывает' h' на 'l'. Но тогда установка 'h = h * 2' указывает' h' на что-то другое. – BrenBarn

ответ

2

Условное обозначение h указывает на то же изделие, что и l. Тем не менее, он не надолго сваривает два. Когда вы меняете h с h = h * 2, вы сообщаете Python о создании удвоенной версии в другом месте в памяти, а затем создайте h, указывая на удвоенную версию. Вы не указали никаких изменений для изменения l; который все еще указывает на исходный элемент.

7

Это довольно просто, чтобы проверить, запустить этот простой тест:

l = [1, 5, 9, 3] 
h = l 

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

print id(h), id(l) 
h = h * 2 
print id(h), id(l) 

print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

Как вы можете видеть из линии h = h * 2, И.Д. ч было изменено

Почему это? Когда вы используете оператор *, он создает новый список (новое пространство памяти). В вашем случае этот новый список присваивается старой ссылке h, поэтому вы можете видеть, что идентификатор отличается от h = h * 2

Если вы хотите узнать больше об этой теме, убедитесь, что вы смотрите на ссылку Data Model.

+0

да, но это не говорит мне * почему * – AlanH

+0

@AlanH Хорошо, я отредактировал свой ответ – BPL

1

В любое время, когда вы назначаете переменную, ее идентификатор (адрес памяти) обычно изменяется - единственная причина, по которой он не изменился, заключается в том, что вам присвоено значение, которое оно уже удерживало. Итак, ваше заявление h = h * 2 заставило h стать совершенно новым объектом - тот, значение которого было основано на предыдущем значении h, но это не имеет никакого отношения к его идентичности.

4

h = h * 2 присваивает h новому объекту.

Вы, вероятно, хотите изменить hна месте:

h *= 2 
print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3, 9, 5, 1, 3] 
+0

Короткие и сладкие ... +1 'h + = h * 2' тоже будут работать. :) –

+0

@ l'L'l Это работает, но не будет ли оно тройным, а не двойным? Вы имели в виду 'h + = h'? –

+1

Да, спасибо за исправление, вот что я имел в виду, мой телефон как-то оставил * 2 ... там. –

1

Это сложно, но когда вы умножаете список, вы создаете новый список.

l = [1, 5, 9, 3] 
h = l 

«l» и «h» теперь относятся к одному и тому же списку в памяти.

h[0], h[2] = h[2], h[0] 

print(h) # [9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

Вы поменялись местами значения в h, так что значения изменяются в l.Это имеет смысл, когда вы думаете о них, как разные имена для того же объекта

h = h * 2 

print(h) # [9, 5, 1, 3, 9, 5, 1, 3] 
print(l) # [9, 5, 1, 3] 

При умножении h * 2, вы создаете новый список , так что теперь только l будет исходный объект списка.

>>> l = [1, 5, 9, 3] 
>>> h = l 
>>> id(h) == id(l) 
True 
>>> id(h) 
139753623282464 
>>> h = h * 2 
>>> id(h) == id(l) 
False 
>>> id(h) 
139753624022264 

Посмотрите, как id из h изменений после умножения? Оператор * создает новый список, в отличие от другой операции с списком, например append(), которые изменяют текущий список.

Надеюсь, это поможет!

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