Почему списки отличаются друг от друга, если их тип и контент одинаковы? [Дубликат]

Мне не повезло с решениями, предлагаемыми на этой странице раньше, но потом, наконец, этот небольшой трюк сработал. Я включу его в другое возможное решение.

  footer {position: fixed;  право: 0;  bottom: 0;  left: 0;  обивка: 1rem;  background-color: #efefef;  text-align: center;  }  
75
задан Peter Mortensen 22 November 2014 в 15:41
поделиться

9 ответов

Вы неправильно поняли, что тестирует оператор is. Он проверяет, указывают ли две переменные на тот же объект , если две переменные имеют одинаковое значение.

Из документации для оператора is :

Операторы is и is not проверяют идентичность объекта: x is y истинно тогда и только тогда, когда x и y являются одним и тем же объектом.

< / blockquote>

Вместо этого используйте оператор ==:

print x == y

Отправляет True. x и y представляют собой два отдельных списка:

x[0] = 4
print y  # prints [1, 2, 3]
print x == y  # prints False

Если вы используете функцию id() , вы увидите, что x и y имеют разные идентификаторы:

>>> id(x)
4401064560
>>> id(y)
4401098192

, но если вы должны назначить y на x, то оба указывают на один и тот же объект:

>>> x = y
>>> id(x)
4401064560
>>> id(y)
4401064560
>>> x is y
True

и is показывают, что оба являются одним и тем же объектом, он возвращает True.

115
ответ дан wim 17 August 2018 в 09:46
поделиться
  • 1
    Таким образом, A is B совпадает с id(A) == id(B). – imallett 12 July 2016 в 22:29
  • 2
    @imallett: это прокси-сервер для одного и того же теста, если вы не сохраняете id(A) в переменной, а затем ожидаете variable == id(B), чтобы все еще работать; если A был удален в то же время, тогда B может быть предоставлено одно и то же место памяти. – Martijn Pieters♦ 13 July 2016 в 10:39
  • 3
    Имеет смысл, и это также правильная вещь; variable хранит свойство того, что раньше существовало. Для среды выполнения нет возможности обнаружить, что более позднее использование ошибочно. Ключевой частью стандарта является «[id ()], который гарантированно является уникальным и постоянным для этого объекта в течение его срока службы . Два объекта с неперекрывающимися временами жизни могут иметь одинаковое значение id (). & Quot; – imallett 13 July 2016 в 21:19
  • 4
    Не удалось форматировать комментарии. Но есть интересная вещь. : & gt; & gt; & gt; & gt; & gt; x = 5 \n & gt; & gt; & gt; & gt; & gt; y = 5 \n & gt; & gt; & gt; & gt; x - y \n Истина \n & gt; & gt; & gt; & gt; & gt; x == y \n Истина \n & gt; & gt; & gt; & gt; & gt; \n – Haranadh 6 June 2017 в 05:27
  • 5
    Малые целые числа интерполируются в CPython, так как они используются так часто. Это оптимизация. x = 5; y = 5; x - y = & gt; Истинно, потому что id (x) == id (y). Это тот же целочисленный объект, который используется повторно. Работает на Python, поскольку целые числа неизменяемы. Если вы делаете x = 1.0; y = 1.0 или x = 9999; y = 9999, это не будет идентичная идентификация, так как float и более крупные ints не интернированы. – Magnus Lyckå 21 September 2017 в 13:56

С помощью дублированного вопроса , эта аналогия может работать:

# - Darling, I want some pudding!
# - There is some in the fridge.

pudding_to_eat = fridge_pudding
pudding_to_eat is fridge_pudding
# => True

# - Honey, what's with all the dirty dishes?
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling.
# - But there was already some in the fridge.

pudding_to_eat = make_pudding(ingredients)
pudding_to_eat is fridge_pudding
# => False
32
ответ дан Community 17 August 2018 в 09:46
поделиться
  • 1
    Может быть, это был личный вкус (не каламбур), но я нашел эту аналогию более запутанной, чем полезной, и заставил меня хотеть есть пудинг, когда у меня нет в моем холодильнике :( Я думаю, что ответ Марка Рэнсома, хотя и более скучный, вероятно, более поучительный – Tom Close 1 October 2015 в 06:47
  • 2
    @TomClose: Есть много прекрасных ответов на этот вопрос, достаточно, чтобы было место для легкомыслия. Кроме того, я тоже хочу пудинг. – Amadan 1 October 2015 в 06:49

Как вы можете проверить здесь на маленькие целые числа. Числа выше 257 не являются маленькими ints, поэтому он вычисляется как другой объект.

В этом случае лучше использовать ==.

Дополнительная информация находится здесь: http://docs.python.org/2/c-api/int.html

2
ответ дан CS Gamer 17 August 2018 в 09:46
поделиться

is и is not - два тождественных оператора в Python. Оператор is не сравнивает значения переменных, а сравнивает тождества переменных. Рассмотрим это:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> hex(id(a))
'0x1079b1440'
>>> hex(id(b))
'0x107960878'
>>> a is b
False
>>> a == b
True
>>>

В приведенном выше примере показано, что идентификатор (также может быть адресом памяти в Cpython) отличается как для a, так и b (хотя их значения одинаковы ). Вот почему, когда вы говорите a is b, он возвращает false из-за несоответствия в тождествах обоих операндов. Однако, когда вы говорите a == b, он возвращает true, потому что операция == проверяет, имеет ли оба операнда одно и то же значение, присвоенное им.

Интересный пример (для дополнительной оценки):

>>> del a
>>> del b
>>> a = 132
>>> b = 132
>>> hex(id(a))
'0x7faa2b609738'
>>> hex(id(b))
'0x7faa2b609738'
>>> a is b
True
>>> a == b
True
>>>

В приведенном выше примере, хотя a и b являются двумя разными переменными, a is b возвращен True. Это связано с тем, что тип a является int, который является неизменным объектом. Таким образом, python (я думаю, чтобы сохранить память) выделил тот же объект b, когда он был создан с тем же значением. Таким образом, в этом случае идентичности согласованных переменных и a is b оказались True.

Это применимо ко всем неизменяемым объектам:

>>> del a
>>> del b
>>> a = "asd"
>>> b = "asd"
>>> hex(id(a))
'0x1079b05a8'
>>> hex(id(b))
'0x1079b05a8'
>>> a is b
True
>>> a == b
True
>>>

Надеюсь, что помогает.

4
ответ дан fluffy 17 August 2018 в 09:46
поделиться

is возвращает true только в том случае, если они фактически являются одним и тем же объектом. Если бы они были одинаковыми, изменение в одном было бы также показано в другом. Вот пример разницы.

>>> x = [1, 2, 3]
>>> y = [1, 2, 3]
>>> print x is y
False
>>> z = y
>>> print y is z
True
>>> print x is z
False
>>> y[0] = 5
>>> print z
[5, 2, 3]
6
ответ дан Mark Ransom 17 August 2018 в 09:46
поделиться

Он сравнивает идентификатор объекта, то есть, относятся ли переменные к одному и тому же объекту в памяти. Это похоже на == в Java или C (при сравнении указателей).

1
ответ дан mipadi 17 August 2018 в 09:46
поделиться

X указывает на массив, Y указывает на другой массив. Эти массивы идентичны, но оператор is будет смотреть на те указатели, которые не идентичны.

2
ответ дан Neko 17 August 2018 в 09:46
поделиться
  • 1
    У Python нет указателей. Вам нужно подтянуть свою терминологию. – David Heffernan 30 November 2012 в 19:40
  • 2
    Это делается внутренне, как Java и так много других языков. Фактически, функциональность оператора is показывает это. – Neko 30 November 2012 в 19:41
  • 3
    Детали реализации не имеют значения. Документация использует терминологию «идентичность объекта». Так и должно быть. «Операторы являются и не проверяют идентификатор объекта: x является y истинным тогда и только тогда, когда x и y являются одним и тем же объектом. x не означает, что y дает обратное значение истинности. – David Heffernan 30 November 2012 в 19:45
  • 4
    @Neko: CPython внутренне использует указатели. Но, очевидно, Jython (реализованный в Java) и PyPy (реализованный в подмножестве Python) не используют указатели. В PyPy некоторые объекты даже не будут иметь id, если вы не попросите его. – abarnert 10 September 2014 в 06:40

x is y совпадает с id(x) == id(y), сравнивая идентичность объектов.

Как отметил @ tomasz-kurgan в комментарии ниже is, оператор ведет себя необычно с определенными объектами.

Например,

>>> class A(object):
...   def foo(self):
...     pass
... 
>>> a = A()
>>> a.foo is a.foo
False
>>> id(a.foo) == id(a.foo)
True

Ref; https://docs.python.org/2/reference/expressions.html#is-not https://docs.python.org/2/reference/expressions.html#id24

3
ответ дан Nizam Mohamed 17 August 2018 в 09:46
поделиться
  • 1
    Нет, это не так. В большинстве случаев это может вести себя аналогично, но это не всегда так. См. это - самое нижнее значение страницы, bullet 6 .: & gt; (...), вы можете заметить, по-видимому, необычное поведение в некоторых применениях - это оператор , как и те, которые связаны с сравнениями между методами экземпляра или константами. И минимальный рабочий пример: `class A (object): def foo (self): передать a = A () print a.foo - это идентификатор печати a.foo (a.foo) == id (a.foo) ` – Tomasz Kurgan 26 June 2018 в 11:23
  • 2
    @ tomasz-kurgan Спасибо – Nizam Mohamed 29 June 2018 в 18:48
33
ответ дан Community 6 September 2018 в 07:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: