2016-07-15 23 views
1

Я смущен.Кортеж строк «есть» сравнение ведет себя непоследовательно

foo = ("empty", 0) 
foo[0] is "empty" 

Возврат Неверно. Кажется, что это проблема с ключевыми строками, так как «список» также терпит неудачу. «empt» и другие строки верны. Кажется, что это происходит только с кортежами, как если бы foo был списком, код также возвращает true

Я тестировал это с помощью python 3.4.3 и python 3.5, и оба ведут себя таким образом, python2.7 не кажется эта проблема хотя и возвращает true, как ожидалось.

Я пропустил какой-то стандарт на кортежах в python3? Я попытался решить эту проблему google-foo, но я не понимаю.

Edit: Чтобы очистить вещи, мой точный вопрос, почему же

foo = ("empty", 0) 
foo[0] is "empty" 

возвращение Ложные, но

foo = ("empt", 0) 
foo[0] is "empt" 

возвращение Правда?

+2

You're * сравнение струнные *. Почему вы решили использовать 'is', а не' == '? –

+1

Потому что эти два не являются буквально одним и тем же объектом, что и для '' '' 'тестов. Они равны. * – kindall

+0

't = (" list ",); t [0] является «списком» 'evalutes к' False' и 't = (" notlist ",); t [0] является «notlist» '' 'True'. Я думаю, что это суть вопроса. – mhoff

ответ

0

Как другие ответы уже упоминалось: Вы сравниваете строки идентичностью, и это, вероятно, не в состоянии. Предположения об идентичности строковых литералов не могут быть сделаны.

Однако на самом деле вы нашли тонкий вопрос.

>>> t = ("list",); t[0] is "list" 
False 
>>> t = ("notlist",); t[0] is "notlist" 
True 
>>> t = ("list",) 
>>> id(t[0]) 
140386135830064 
>>> id("list") 
140386137208400 
>>> t[0] is "list" 
False 
>>> l = ("notlist",) 
>>> id(l[0]) 
140386135830456 
>>> id("notlist") 
140386135830456 
>>> l[0] is "notlist" 
True 
# interestingly, this works: 
>>> ("list",)[0] is "list" 
True 

(Испытано с Python 3.5.1+ интерактивной оболочки)

Это явно зависит от реализации поведение какого-либо компонента питона, предположительно лексером или синтаксического анализа.

Нижняя строка: используйте сравнение ==, если вы не зависите от идентификации объекта.

+0

Вы принимаете правильно; нет причин ожидать, что '(" list ",) [0] является" list ", чтобы быть истинным. Интерпретатор может свободно выделять отдельные объекты для каждого литерала. – chepner

+0

«тонкий вопрос» - нет, не проблема. Python не дает никаких обещаний, что это поведение будет нарушено. – user2357112

+0

У вас есть лучшее слово для этого поведения? Я знаю, что это не нарушение. Тем не менее, это не очень интуитивно понятно, так как строка *, содержащая * ключевое слово python, кажется ничего особенного. – mhoff

0

Использование буквального значения с is почти наверняка даст вам результат, зависящий от реализации. Единственный литерал, который Python гарантирует, что он синглтон, - None. Любой другой литерал может или не может ссылаться на ссылку на существующий объект. Вы не можете предположить, что интерпретатор «распознает» дублирующее значение и использует один и тот же базовый объект для его представления.