0

According to Python id documentation returns the object's identity which in CPython is its memory address, and the is operator checks if two objects are identical (which I assume should be in the same RAM memory). Consider the snippet below:

>>> a = "999"
>>> b = a
>>> id(tuple(a)) == id(tuple(b))
True
>>> tuple(b) is tuple(a)
False

Why the second expression evaluates to False?

I read this question and this one but still don't know (though have some guesses) what's the exact cause for the behavior. Because both objects are still in memory and not simple strings or integers to be interned. I couldn't completely decipher the generated byte-code using the dis.dis.

I appreciate if you take the time to provide some explanation or reference before marking it as duplicate or down-voting.

  • When an object goes out of scope, its id can be reused. Don’t rely solely on id equality or inequality to tell you whether two expressions produce the same object. Using `is` should be safe, but calling `id` and comparing the results is not. – Samwise Mar 18 '23 at 00:47
  • @Samwise In which part and which object do you mean goes out of scope? – Mohammad FS Mar 18 '23 at 00:51
  • Your tuples go out of scope as soon as they’ve been evaluated. In your first comparison, `tuple(a)` goes out of scope before `tuple(b)` is constructed, so they end up sharing an id. – Samwise Mar 18 '23 at 00:51
  • @Samwise I know they're not held in memory, but why in the first case they're always evaluated as one but not in the second comparison? – Mohammad FS Mar 18 '23 at 00:53
  • I think the difference is that in the first case, the first tuple is freed after id() returns. In the second case, both tuples are needed to evaluate the `is`, so they both exist in memory at the same time. – Samwise Mar 18 '23 at 00:54
  • @Samwise My main guess was what you're saying as I didn't see any `STORE_NAME` or alike instructions in the byte-code, but do you have actual proof or reference for this? – Mohammad FS Mar 18 '23 at 00:56
  • The exact mechanics are unimportant IMO, because that’s an implementation detail that could change at any point, and therefore shouldn’t factor into the code you write. Make no assumptions about what id() returns and you’ll never be unpleasantly surprised. – Samwise Mar 18 '23 at 01:00
  • @Samwise it's a matter of curiosity and developing a deeper understanding; Although as stated in the doc in the first link **"CPython implementation detail: This is the address of the object in memory."** Thanks anyway and I will keep waiting and searching. – Mohammad FS Mar 18 '23 at 01:04
  • 3
    "I appreciate if you take the time to provide some explanation or reference before marking it as duplicate" - why? This duplicate is about as exact as it gets, and the question is asked frequently. – Karl Knechtel Mar 18 '23 at 01:09
  • @KarlKnechtel I know the basics of how `is` and `id` work and read other sources and in none of them the same scenario was explained. I'm looking for the exact mechanics of why checking with `id` results `True` but not when checking with the `is` operator, which again is not what I could find anywhere else. – Mohammad FS Mar 18 '23 at 01:33
  • 1
    "I'm looking for the exact mechanics of why checking with id results True but not when checking with the is operator, which again is not what I could find anywhere else." That happens because your scenario is equivalent to the one in the question that I have now linked as a duplicate, and the specific reasons are as described in the answers for that question. If I were to add an explanation here, I would effectively be copying and pasting from those answers. – Karl Knechtel Mar 18 '23 at 02:00

0 Answers0