id(t+t), id(t*2)
(42838592, 42838592)
(t+t) is (t*2)
False
If two variable point to same object 'is' operator will return true.But first line said both have same id but 'is' operator give false value.
In the first example, your objects don't overlap in time: one is created then destroyed, then another is created with the same id.
When you compare them with is, you are holding onto both objects, so they get different ids.
As explained by Ned Batchelder's answer, and by the docs for the id function:
Two objects with non-overlapping lifetimes may have the same
id()value.
And the two objects have non-overlapping lifetimes.
The fact that they're part of the same tuple expression doesn't change that, because it's not t+t and t*2 that are part of a tuple, it's id(t+t) and id(t*2). So, those two integer values returned by id have an overlapping lifetime, but the arguments passed to id do not.
One way to understand this is to look at how CPython compiles the code:
>>> dis.dis('id(t+t), id(t*2)')
1 0 LOAD_NAME 0 (id)
2 LOAD_NAME 1 (t)
4 LOAD_NAME 1 (t)
6 BINARY_ADD
8 CALL_FUNCTION 1
10 LOAD_NAME 0 (id)
12 LOAD_NAME 1 (t)
14 LOAD_CONST 0 (2)
16 BINARY_MULTIPLY
18 CALL_FUNCTION 1
20 BUILD_TUPLE 2
22 RETURN_VALUE
So, here's what happens. (I'm going to pick a value for t, say 1000, just to make this a bit easier to follow.)
id, 1000, and 1000 get pushed on the stack.BINARY_ADD creates a 2000 value at location 42838592.id gets called on that value and returns a 42838592 value at location, say, 42838616.42838592 value is no longer on the stack and wasn't stored anywhere, id's parameter was the only reference to it, so when it gets decrefed at the end of the function, it's immediately deleted.id, 1000, and 2 get pushed on the stack.BINARY_MULTIPLY creates a new 2000 object. Since location 42838592 was just returned to the object pool, the new value reuses that location.id returns another 42838592, this time at location, say, 42838640.So, the two int values 4283592 and 4283592 have overlapping lifetimes (and the first one overlaps with the second 2000), the two 2000s do not overlap.
And finally, notice that if t is a small number,
>>> t = 2
>>> (t+t) is (t*2)
True
… because all 4 values (except in unusual cases) are references to the same object.
And meanwhile, if t is a constant rather than a variable, 1000+1000 is 1000*2 may or may not be true, depending on your CPython version, because of the way constant folding within a compilation unit works.
All of which goes to show that trying to actually take advantage of whether two equal ints are or are not the same object is pretty much always a terrible idea. The only reason you should ever care about this question is if you're trying to learn more about the internals of CPython.
And of course this is all CPython-specific. Most other Python interpreters use some form of garbage collector instead of refcounting, so the first 2000 is unlikely to be destroyed before the second one is created. Plus, not all of them use an object pool like CPython. Not to mention that they're allowed to do completely different things for id as long as they can guarantee unique values for non-overlapping objects.
PyPy will actually usually return the same value here—but only because it folds t+t and t*2 into the same object in the first place; try it with t+t and t*3and you'll get completely differentid`s.
t2a, t2b = t+t, t*2. Then they won't have the sameid(except when they're the same object because of the small-int optimization or compiler constant folding, of course…)idfunction.is(and they're not the same as each other, either).t+torobj.methors[0:3]are, and know the lifetimes of each of those objects. Theid()documentation says nothing at all about either of those.