2

I thought everything below would evaluate to False. Can someone explain what is going on? Don't immutable constructors create new objects (and new ids)? How can the tuple have the same id and be different objects?

print((1,) is (1,))
print(id(1,) == id(1,))
print('a' is 'a')
print(id('a') == id('a'))

Result:

False
True
True
True
Mike Müller
  • 82,630
  • 20
  • 166
  • 161

4 Answers4

4

Your second line is incorrect. You are passing 1 to id. (Python allows trailing commas in argument lists.)

print((1,) is (1,))
print(id((1,)) == id((1,)))
print('a' is 'a')
print(id('a') == id('a'))

Which are

False
False
True
True

So the results from id and is match.


It should be noted that the results of is/id can vary by implementation.

For example, in CPython 2.7, 2 * 2 is 4 but 2 * 200 is not 400. For low integer vales, CPython uses the same memory addresses (which are the results of id in CPython). Again, this varies by implementation.

dawg
  • 98,345
  • 23
  • 131
  • 206
Paul Draper
  • 78,542
  • 46
  • 206
  • 285
  • I've been using Python forever, and I never knew that it allowed a trailing (not trialing!) comma in a parameter list. Thanks for that! – Mark Ransom Sep 11 '15 at 03:17
0

You construct a new instance of the immutable type with every instance of a tuple. The values of the tuple cannot change, but they are different (although equal) instances.

Dmitry Rubanovich
  • 2,471
  • 19
  • 27
0

It is probable that you can see the results of interning with immutable objects in Python, Java, and others.

PEP237 states:

  • Short ints with small values (typically between -1 and 99 inclusive) are "interned" -- whenever a result has such a value, an existing short int with the same value is returned. This is not done for long ints with the same values. This difference will remain. (Since there is no guarantee of this interning, is is debatable whether this is a semantic difference -- but code may exist that uses 'is' for comparisons of short ints and happens to work because of this interning. Such code may fail if used with long ints.)

Examples:

>>> x=7
>>> y=10-3
>>> z=int('7')
>>> all(7 is e for e in [x,y,z])
True
>>> map(id, [x,y,z])
[140410571769784, 140410571769784, 140410571769784]

Strings:

>>> s1='abc'
>>> s2='abc'
>>> s1 is s2
True
>>> id(s1)
4378429560
>>> id(s2)
4378429560

You cannot rely on an instance of an immutable object being the only label of that object. It is an implementation detail that can vary across versions and implementations.

dawg
  • 98,345
  • 23
  • 131
  • 206
0
print((1,) is (1,))
print(id(1,) == id(1,))
print('a' is 'a')
print(id('a') == id('a'))

1- first evaluates to false because the 2 tuples are different objects

2- it evaluates to true because id(1,) doesn't recognise 1, as a tuple but just as a 1, and when you have small integers or strings python does an optimisation where it references 2 names to the same id so it doesn't have to allocate 2 different spaces. It'd be false if you had id((1,)) since then it'd recognise it as a tuple

3 and 4 - they're true for the same reason as 2 is true

Fabio
  • 3,015
  • 2
  • 29
  • 49