1

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?

kalsl
  • 23
  • 3

3 Answers3

0
a is b

Equals to

id(a) == id(b)

As mentioned here Comparing strings Also read this Built-in Functions - id

Community
  • 1
  • 1
UpmostScarab
  • 960
  • 10
  • 29
0

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.

Michael Hoff
  • 6,119
  • 1
  • 14
  • 38
  • You assume correctly; there is no reason to expect `("list",)[0] is "list"` to be true, either. An interpreter is free to allocate separate objects for each literal. – chepner Jul 15 '16 at 22:42
  • "subtle issue" - nope, not an issue. Python makes no promises that this behavior would violate. – user2357112 Jul 15 '16 at 22:43
  • Do you have a better word for this behavior? I know that this is no violation. However, it is not very intuitive, as a string *containing* a python keyword seems nothing special. – Michael Hoff Jul 15 '16 at 22:47
  • Neat, the behavior seemed to be dependent on keywords or something. Good to know this falls into the undefined territory with is comparisons. – kalsl Jul 15 '16 at 22:53
0

Using a literal value with is is almost certainly going to give you an implementation-dependent result. The only literal that Python guarantees to be a singleton is None. Any other literal may or may not resolve to a reference to an existing object. You can't assume that the interpreter will "recognize" the duplicate value and use the same underlying object to represent it.

chepner
  • 497,756
  • 71
  • 530
  • 681