Как проверить, ссылаются ли две переменные на один и тот же объект?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Как проверить, ссылаются ли две переменные на один и тот же объект?
x = ['a', 'b', 'c']
y = x # x and y reference the same object
z = ['a', 'b', 'c'] # x and z reference different objects
Ответы:
Вот для чего is: x is yвозвращает, Trueесли xи yявляются одним и тем же объектом.
x is zвозвращается False. Но если x и z присваиваются одинаковые значения вместо списков (например x, z = 13, 13), x is zвозвращается True. Почему это?
xи zточке. Поскольку маленькие целые числа являются обычным явлением (-1 как значение ошибки, 0 каждый раз, когда вы действительно что-то индексируете, маленькие числа обычно являются разумными значениями по умолчанию) Python оптимизирует, предварительно выделяя маленькие числа (от -5 до 256) и повторно используя один и тот же целочисленный объект. Таким образом, ваш пример работает только для чисел в этом диапазоне. Попробуйте назначить что - то большее, то есть 270. Для получения дополнительной информации смотрите здесь
isпроверяет, ссылаются ли два имени на одну и ту же ячейку памяти. Это не имеет ничего общего с самим объектом. Легко иметь неизменяемые объекты, такие как строки, которые равны, но не хранятся в одном и том же месте, например ''a'*10000 is 'a' * 10000False.
"af" is "af"или () is ()... почему они используют одну и ту же ячейку памяти?
y is xбудет True, y is zбудет False.
Вы также можете использовать id (), чтобы проверить, к какому уникальному объекту относится каждое имя переменной.
In [1]: x1, x2 = 'foo', 'foo'
In [2]: x1 == x2
Out[2]: True
In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)
In [4]: x2 = 'foobar'[0:3]
In [5]: x2
Out[5]: 'foo'
In [6]: x1 == x2
Out[6]: True
In [7]: x1 is x2
Out[7]: False
In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)
В то время как два правильных решений x is zи id(x) == id(z)уже отвечал, я хочу отметить деталь реализации питона. Python хранит целые числа как объекты, в качестве оптимизации он генерирует кучу небольших целых чисел в начале (от -5 до 256) и указывает КАЖДУЮ переменную, содержащую целое число с небольшим значением, на эти предварительно инициализированные объекты. Больше информации
Это означает, что для целочисленных объектов, инициализированных одними и теми же небольшими числами (от -5 до 256), проверка идентичности двух объектов вернет истину ( ON C-Pyhon , насколько мне известно, это деталь реализации ), а для более крупных числа это возвращает истину, только если один объект инициализирован из другого.
> i = 13
> j = 13
> i is j
True
> a = 280
> b = 280
> a is b
False
> a = b
> a
280
> a is b
True
Мне очень нравится визуальная обратная связь, поэтому я иногда просто открываю http://www.pythontutor.com/visualize.html#mode=edit, чтобы увидеть, как распределяется память и что на что ссылается.
Добавил эту потрясающую гифку, так как этот ответ о визуализации ..
Это взято с сайта docs.python.org: «Каждый объект имеет идентификатор, тип и значение. Идентификатор объекта никогда не изменяется после его создания; вы можете думать об этом как об адресе объекта в памяти. Оператор« есть » сравнивает идентичность двух объектов; функция id () возвращает целое число, представляющее его идентичность ".
По-видимому, каждый раз, когда вы меняете значение, объект воссоздается, на что указывает изменение идентификатора. Строка x = 3, за которой следует строка x = 3.14, не дает ошибок и дает разные идентификаторы, типы и значения для x.
xэто имя идентификации объекта с значением из 3, а не как объект сам по себе. Когда вы это сделали x=3.14, вы не изменили объект, который ранее был идентифицирован x- вы изменили объект, к которому относится имя x .