В этом примере x is zвозвращается False. Но если x и z присваиваются одинаковые значения вместо списков (например x, z = 13, 13), x is zвозвращается True. Почему это?
Билл
12
@Bill: Это артефакт того, как Python обрабатывает целые числа. Python выделяет целое число объектов , к которым xи zточке. Поскольку маленькие целые числа являются обычным явлением (-1 как значение ошибки, 0 каждый раз, когда вы действительно что-то индексируете, маленькие числа обычно являются разумными значениями по умолчанию) Python оптимизирует, предварительно выделяя маленькие числа (от -5 до 256) и повторно используя один и тот же целочисленный объект. Таким образом, ваш пример работает только для чисел в этом диапазоне. Попробуйте назначить что - то большее, то есть 270. Для получения дополнительной информации смотрите здесь
ted
1
@AndresR Нет, это неправильно. isпроверяет, ссылаются ли два имени на одну и ту же ячейку памяти. Это не имеет ничего общего с самим объектом. Легко иметь неизменяемые объекты, такие как строки, которые равны, но не хранятся в одном и том же месте, например ''a'*10000 is 'a' * 10000False.
Йохен Ритцель
1
@JochenRitzel Вы совершенно правы, спасибо за этот комментарий! Итак, я не понимаю, что происходит "af" is "af"или () is ()... почему они используют одну и ту же ячейку памяти?
AndresR
2
@AndreasR Для буквальных строк / чисел в коде компилятор проверяет, существуют ли они только один раз, и повторно использует их. Специальные значения, такие как (), None, True, False и т. Д., Также определены как одиночные. Во время выполнения среда выполнения также пытается повторно использовать небольшие числа и строки, но в конечном итоге это компромисс между скоростью и памятью, и то, что происходит, зависит от того, как была реализована среда выполнения Python.
Замечание @ted об использовании id здесь весьма актуально.
Лев Уфимцев
11
В то время как два правильных решений 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
Это взято с сайта docs.python.org: «Каждый объект имеет идентификатор, тип и значение. Идентификатор объекта никогда не изменяется после его создания; вы можете думать об этом как об адресе объекта в памяти. Оператор« есть » сравнивает идентичность двух объектов; функция id () возвращает целое число, представляющее его идентичность ".
По-видимому, каждый раз, когда вы меняете значение, объект воссоздается, на что указывает изменение идентификатора. Строка x = 3, за которой следует строка x = 3.14, не дает ошибок и дает разные идентификаторы, типы и значения для x.
xэто имя идентификации объекта с значением из 3, а не как объект сам по себе. Когда вы это сделали x=3.14, вы не изменили объект, который ранее был идентифицирован x- вы изменили объект, к которому относится имяx .
Ответы:
Вот для чего
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' * 10000
False."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
.