kalsl kalsl - 4 months ago 7
Python Question

tuple of strings "is" comparison behaves inconsistently

I'm confused.

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


Returns False. This seems to be a problem with keyword strings, as "list" fails as well. "empt" and other strings return true. This only seems to happen with tuples, as if foo is a list the code also returns true

I've tested this with python 3.4.3 and python 3.5 and both behave this way, python2.7 doesn't seem to have this issue though and returns true as expected.

Am I missing some standard on tuples in python3? I've attempted to google-foo this problem but am coming up short.

Edit:
To clear things up, my exact question is why does


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


return False, but

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


return True?

Answer

As the other answers already mentioned: You are comparing strings by identity and this is likely to fail. Assumptions about the identity of string literals can not be made.

However, you actually found a subtle issue.

>>> 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

(Tested with Python 3.5.1+ interactive shell)

This is plainly implementation-dependent behavior by some component of python, presumably lexer or parser.

Bottom-line: Use == for string comparison, as long as you do not depend on object identity.

Comments