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
не дают те же результаты?
6 ответов
задание делает h укажите на тот же элемент, что и l. Тем не менее, он не постоянно сваривает два. При изменении h С h = h * 2, вы говорите Python построить удвоенную версию в другом месте в памяти, а затем сделать h укажите на удвоенную версию. Вы не давали никаких инструкций, чтобы изменить l; это все еще указывает на исходный элемент.
Это довольно просто проверить, выполните этот простой тест:
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, поэтому вы можете видеть, что id отличается после h = h * 2
если вы хотите узнать больше об этом предмете, убедитесь, что вы смотрите на сведения Модель ссылка.
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]
в любое время, когда вы назначаете переменной, ее идентификатор (адрес памяти) обычно меняется - единственная причина, по которой он не изменится, заключается в том, что вы назначили ему значение, которое он уже держал. Итак, ваше заявление h = h * 2
заставил h стать совершенно новым объектом - тем, значение которого было основано на предыдущем значении h, но это не имеет отношения к его идентичности.
это сложно, но когда вы умножаете список, вы создаете новый список.
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
of h
изменения после умножения? The *
оператор создает новый список, в отличие от других список операций, таких как append()
, которые изменяют текущий список.
>>> h.append(1000)
>>> id(h)
139753623282464 # same as above!
надеюсь, что это помогает!
import numpy as np
print np.may_share_memory(l,k)
помогает подтвердить, что две переменные l и k имеют одинаковую память