1

Why when I compare two equal tuples through the operator (is) I get a different result than when I compare two equal lists? (one is True an the other is False)

Nothing really... i am starting with python and i do not want to leave my doubts :)

a=(1,2,3)
b=(1,2,3)
c=[1,2,3]
d=[1,2,3]
print(a is b) #True
print(c is d) #false

I expected that both were False :(

  • 3
    C is a list and b is a tuple. What’s wrong with the output? a and b are same – Sheldore Dec 20 '18 at 23:48
  • 1
    "I expected that both were False" - well, at least you have a better understanding than if you had expected the results to be True. – user2357112 Dec 20 '18 at 23:51
  • Do you know about "mutability"? – roganjosh Dec 20 '18 at 23:51
  • 2
    CPython is able to intern the tuples, but it won't do that for the lists. There's a dupe somewhere... – wim Dec 20 '18 at 23:51
  • 1
    If you're starting out with Python, you're better off forgetting about the `is` operator for a while. Just use `==`, as it's going to be what you want 99% of the time anyway. – Daniel Pryden Dec 20 '18 at 23:52
  • To add to this - the tuples are interned, so they refer to the same point in memory and would be equivalent. – Makoto Dec 20 '18 at 23:52
  • 3
    @Makoto: Given that the questioner expected both results to be False, it sounds like they know what `is` does. This needs a different dupe target. – user2357112 Dec 20 '18 at 23:52
  • @user2357112: The dupe *does* mention that Python will cache/intern small objects, which is what's happening here, which *does* sufficiently explain OP's case. – Makoto Dec 20 '18 at 23:54
  • @DanielPryden: I recommend remembering `is` solely for use with `None` early on. – ShadowRanger Dec 20 '18 at 23:57
  • @Makoto: It only talks about that for integers, without discussing any general principles that would apply to tuples. – user2357112 Dec 20 '18 at 23:57
  • @user2357112: I mean, if you feel like the dupe is invalid then feel encouraged to cast a reopen vote or edit in a different dupe target. I'm not a gold badge holder and one is lurking around here, so you'll have a better time appealing to them than me. – Makoto Dec 21 '18 at 00:02

1 Answers1

0

Python may optimize small read-only objects (strings, numbers, tuples) by "interning" them (keeping a list of common small objects), or noticing they are the same at compile-time and not making a second copy.

Since these objects can not be changed, this is a safe optimization, and can result in is returning True for two objects that would otherwise be separate.

The actual specifics are version specific and can change from release to release. They are certainly equals (==) , but may or may not be the same (is).

Lists can be modified (they are mutable), therefore, under the current language rules, they have to be viewed as different objects. They have separate identify and are not is the same. Otherwise changing c would change d.

Max
  • 10,701
  • 2
  • 24
  • 48
  • 1
    Not really convincing answer. There is no reason it would be unsafe for CPython to do the same thing for lists (see [CoW](https://en.wikipedia.org/wiki/Copy-on-write)), except that it would probably not be a useful optimization. – wim Dec 20 '18 at 23:54
  • CoW is certainly possible, but `is` is basically the same as id() == id(), and id() is currently defined to be constant for the life of an object. – Max Dec 20 '18 at 23:56
  • Umm... let me right-now "step in, here," and counter-mand your downvote to say that "Max does, in fact, know precisely what he is talking about." Sometimes there is a world of difference between "(" and "[" ... (I shall leave it to subsequent responders to elaborate.) – Mike Robinson Dec 20 '18 at 23:58
  • 2
    @wim: Copy-on-write would either involve two distinct objects with some shared internals (so `is` would still be false), or major changes to the Python evaluation model and the meaning of `is`. – user2357112 Dec 20 '18 at 23:59
  • Yes, in the CoW case for lists, `is` would be false from the start. My gripe is that statement: "it would not be be safe to do this optimization", that's just incorrect. Many systems *do* implement this safely. CPython doesn't bother. – wim Dec 21 '18 at 00:06
  • @wim I can try some different verbiage to indicate that lists are modifiable so have to be viewed as separate objects – Max Dec 21 '18 at 00:07
  • Sure. Or just delete (we don't really need a billionth dupe about CPython interning implementation detail on site IMO) – wim Dec 21 '18 at 00:08