Я был очень удивлен, когда
[] is not []
оценивается как True
.
Что происходит в этом коде? Что действительно делают операторы not
и is
?
Я был очень удивлен, когда
[] is not []
оценивается как True
.
Что происходит в этом коде? Что действительно делают операторы not
и is
?
a is not b
- специальный оператор, эквивалентный not a is b
.
Оператор a is b
возвращает True, если a и b связаны с одним и тем же объектом, иначе False. Когда вы создаете два пустых списка, вы получаете два разных объекта, поэтому is
возвращает False (и поэтому is not
возвращает True).
is
- это сравнение идентичности.
==
- сравнение равенства.
В вашем заявлении написаны два разных списка и проверка того, являются ли они одним и тем же экземпляром, а это не так. Если вы используете ==
, он вернет true и потому что они оба являются пустыми списками.
Лучший способ описать, почему это происходит, это:
Вот ваш пример
>>> x = []
>>> y = []
>>> print(x is y)
... False
x
и y
фактически представляют собой два разных списка, поэтому, если вы добавляете что-то в x
, оно не отображается в y
>>> x.append(1)
>>> print(x)
... [1]
>>> print(y)
... []
Итак, как мы можем сделать (x is y
) значение true?
>>> x = []
>>> y = x
>>> print(x is y)
... True
>>> x.append(10)
>>> print(x)
... [10]
>>> print(y)
... [10]
>>> print(x is y)
... True
если вы хотите увидеть, имеют ли два списка одно и то же содержимое...
>>> x = []
>>> y = []
>>> print(x == y)
... True
>>> x.append(21)
>>> print(x)
... [21]
>>> print(y)
... []
>>> print(x == y)
... False
>>> y = [21]
>>> print(x == y)
... True
is
означает тот же самый экземпляр. Он оценивает значение true, если переменные с обеих сторон оператора указывают на один и тот же объект и false в противном случае.
Ссылка, внизу.
- проверка на тождество. []
и []
- два разных (но эквивалентных) списка. Если вы хотите проверить, что оба списка пустые, вы можете использовать их значение истинности (false для пустых строк, коллекций и нулей).
if not ([] and []):
print 'Spanish Inquisition'
единственный раз, когда is
гарантированно вернет True, для одиночных чисел, таких как None. Как и Highlander, в вашей программе может быть только один экземпляр None. Каждый раз, когда вы возвращаете None, это то же самое "вещь", что и никто, на который вы написали print None
.
[], OTOH, не гарантируется ничем, кроме пустого списка и оценивается как False в булевом контексте.
Я знаю, что отправляю на довольно старый пост. однако это может помочь кому-то наткнуться на меня, как я.
"is" проверяет, совпадает ли адрес памяти или нет, в то время как "==" проверяет, совпадает ли это значение или нет. Было бы ясно из следующего примера.
позвольте сначала поговорить о неизменяемых объектах, так как это легко понять
# could be any immutable object
immutable_a = 10
immutable_b = 10
# prints address of a and b variable
print "address of a is %s" % id(immutable_a)
print "address of a is %s" % id(immutable_b)
# as both addresses is same, following shall be true
print immutable_a is immutable_b
# as the values are also same, following shall be true as well
print immutable_a == immutable_b
теперь поговорим о изменяемых объектах
# could be any mutable object
mutable_a = [10]
mutable_b = [10]
# prints address of a and b variable
print "address of mutable_a is %s" % id(mutable_a)
print "address of mutable_b is %s" % id(mutable_b)
# as addresses are not same, following shall be false
print mutable_a is mutable_b
# as the values are same, following shall be true
print mutable_a == mutable_b
@Jiaaro прав. Использование is
с неизменяемыми типами данных опасно, потому что оно не предсказуемо из-за оптимизации интерпретатора Pythons.
См. этот пример:
10 * "a" is 10 * "a" # True
100 * "a" is 100 * "a" # False
Во второй строке быстрее создать новый объект с новым идентификатором для интерпретатора. Поэтому используйте оператор is
только с изменяемыми типами.