Почему сравнение строк с использованием '==' или 'is' иногда дает другой результат?

Он позволяет группировать набор связанных полей и давать им легенду.

<fieldset>
    <legend>Gender</legend>
    <input type="radio" name="gender" id="male" value="male">
    <label for="male">Male</label>
    <input type="radio" name="gender" id="female" value="female">
    <label for="female">Female</label>
<fieldset>

<fieldset>
    <legend>Address</legend>

    <label for="line1">Line 1</label>
    <input name="address1" id="line1">

    <label for="line2">Line 2</label>
    <input name="address2" id="line2">

    <label for="town">Town</label>
    <input name="town" id="town">

    <label for="country">country/label>
    <input name="country" id="country">
</fieldset>
1039
задан martineau 23 February 2019 в 22:29
поделиться

9 ответов

is - проверка идентичности, == - проверка равенства. то, что происходит в вашем коде, будет эмулироваться в интерпретаторе следующим образом:

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

итак, неудивительно, что они не такие, верно?

Другими словами: is is the id (a) == id (b)

1458
ответ дан 19 December 2019 в 20:19
поделиться

Я думаю, это связано с тем фактом, что, когда сравнение «есть» дает ложное значение, используются два разных объекта. Если он оценивается как истина, это означает, что внутри он использует тот же самый объект, а не создает новый, возможно, потому, что вы создали их в течение доли 2 или около того секунд, и потому что нет большого промежутка времени между его оптимизацией и использует тот же объект.

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

>>> s = 'one'
>>> s2 = 'two'
>>> s is s2
False
>>> s2 = s2.replace('two', 'one')
>>> s2
'one'
>>> s2 is s
False
>>> 

В этом Например, я сделал s2, который был другим строковым объектом, ранее равным 'one', но это не тот же объект, что и s , потому что интерпретатор не использовал тот же объект, который я изначально не назначал к одному',

17
ответ дан 19 December 2019 в 20:19
поделиться

Исходя из моего ограниченного опыта работы с python, is используется для сравнения двух объектов, чтобы увидеть, являются ли они одним и тем же объектом, а не двумя разными объектами с одинаковым значением. == используется для определения идентичности значений.

Вот хороший пример:

>>> s1 = u'public'
>>> s2 = 'public'
>>> s1 is s2
False
>>> s1 == s2
True

s1 - это строка Юникода, а s2 - обычная строка. Они не одного типа, но имеют одно и то же значение.

20
ответ дан 19 December 2019 в 20:19
поделиться

Я считаю, что это известно как «интернированные» строки. Это делает Python, Java, а также C и C ++ при компиляции в оптимизированных режимах.

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

Это приводит к тому, что оператор Python is, возвращающий True, потому что две строки с одинаковым содержимым указывают на один и тот же строковый объект. Это также произойдет в Java и C.

Однако это полезно только для экономии памяти. Вы не можете полагаться на него для проверки равенства строк, потому что различные интерпретаторы, компиляторы и механизмы JIT не всегда могут это сделать.

13
ответ дан 19 December 2019 в 20:19
поделиться

Это второстепенное примечание, но в идиоматическом питоне вы часто будете видеть такие вещи, как:

if x is None: 
    # some clauses

Это безопасно, потому что гарантированно будет один экземпляр нулевого объекта (т. Е. None) .

36
ответ дан 19 December 2019 в 20:19
поделиться

И последнее, что следует отметить, вы можете использовать функцию intern, чтобы убедиться, что вы получаете ссылку на ту же строку:

>>> a = intern('a')
>>> a2 = intern('a')
>>> a is a2
True

Как указано выше, вам, вероятно, не следует делать это для определения равенства строк. Но это может быть полезно, если у вас есть какие-то странные требования для использования is .

Обратите внимание, что функция intern была перемещена из встроенной функции в модуль sys для Python 3.

56
ответ дан 19 December 2019 в 20:19
поделиться

Ключевое слово is - это проверка идентичности объекта, а == - сравнение значений.

Если вы используете , это , результат будет истинным тогда и только тогда, когда объект является тем же самым объектом. Однако == будет истинным каждый раз, когда значения объекта совпадают.

101
ответ дан 19 December 2019 в 20:19
поделиться

Другие ответы здесь верны: is используется для сравнения идентичности , а == используется для равенство сравнение. Поскольку вас волнует равенство (две строки должны содержать одни и те же символы), в этом случае оператор is просто неверен, и вы должны использовать вместо него == .

] Причина, по которой работает в интерактивном режиме, заключается в том, что (большинство) строковых литералов по умолчанию интернированы . Из Википедии:

Интернированные строки ускоряют строку сравнения, которые иногда узкое место в производительности приложений (например, компиляторы и динамические время выполнения языка программирования), что в значительной степени полагаться на хеш-таблицы с строковые ключи. Без интернирования, проверка двух разных строк равны, предполагает изучение каждого характер обеих строк. Это медленно по нескольким причинам: это по сути O (n) в длине струны; обычно требует чтения из нескольких областей памяти, которые занимать время; и чтение заполняет кэш процессора, то есть меньше кеш доступен для других нужд. С интернированные строки, простой объект проверка личности достаточна после оригинальная стажировка; это обычно реализуется как указатель проверка на равенство, обычно всего один машинная инструкция без памяти ссылка вообще.

Итак, когда у вас есть два строковых литерала (слова, которые буквально вводятся в исходный код вашей программы, заключены в кавычки) в вашей программе, которые имеют одинаковое значение, компилятор Python автоматически вставляет строки, сохраняя их в одной и той же ячейке памяти. (Обратите внимание, что это не всегда , и правила, когда это происходит, довольно запутаны, поэтому, пожалуйста, не полагайтесь на такое поведение в производственном коде!)

Поскольку в вашем интерактивном сеансе оба Строки на самом деле хранятся в одной и той же ячейке памяти, они имеют одинаковый идентификатор , поэтому оператор is работает должным образом. Но если вы создаете строку каким-либо другим способом (даже если эта строка содержит точно тех же символов),

539
ответ дан 19 December 2019 в 20:19
поделиться

Если вы не уверены, что делаете, используйте '=='. Если у вас есть немного больше знаний об этом, вы можете использовать 'is' для известных объектов, таких как 'None'.

В противном случае вы будете задаваться вопросом, почему что-то не работает и почему это происходит:

>>> a = 1
>>> b = 1
>>> b is a
True
>>> a = 6000
>>> b = 6000
>>> b is a
False

Я даже не уверен, что некоторые вещи гарантированно останутся неизменными в разных версиях / реализациях python.

27
ответ дан 19 December 2019 в 20:19
поделиться
Другие вопросы по тегам:

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