Skip to content

Instantly share code, notes, and snippets.

@suvayu
Created May 28, 2019 04:50
Show Gist options
  • Save suvayu/dba96d5453680c891e32b3cdee68096c to your computer and use it in GitHub Desktop.
Save suvayu/dba96d5453680c891e32b3cdee68096c to your computer and use it in GitHub Desktop.
Quirks about `id`

Quirks about id

Integers

In [1]: a = 5
In [2]: b = a
In [3]: a is b
Out[3]: True
In [4]: c = 5
In [5]: a is c
Out[5]: True

They behave differently when they are inside a tuple:

In [6]: a = (5,)
In [7]: c = (5,)
In [8]: a is c
Out[8]: False
In [9]: a == c
Out[9]: True

Strings

Similar behaviour for strings:

In [10]: 'foo' is 'foo'
Out[10]: True
In [11]: a, c = 'foo', 'foo'
In [12]: a is c
Out[12]: True
In [13]: a, c = ['foo'], ['foo']
In [14]: a is c
Out[14]: False
In [15]: a == c
Out[15]: True

Why?

is compares the actual memory locations, so if they are indeed the same object, they will be equal. Whereas if they are merely equal, they will won't be.

In [16]: id(a) == id(c)
Out[16]: False
In [17]: id(a), id(c)
Out[17]: (140582292221704, 140582291823496)
In [18]: a, c = 'foo', 'foo'
In [19]: id(a) == id(c)
Out[19]: True
In [20]: id(a), id(c)
Out[20]: (140582907670120, 140582907670120)

Floats

In [21]: 1.2 is 1.2
Out[21]: True
In [22]: a, c = 1.2, 1.2
In [23]: a is c
Out[23]: False
In [24]: id(a), id(c)
Out[24]: (140582332253240, 140582332253336)
In [25]: b = a
In [26]: a is a
Out[26]: True

Floats behave more reasonably, this is because int and str are optimised to always be represented by the same memory location if the values are equal. So two completely unrelated integers, if they are both 5, then they will pass the is-test. Similarly for floats, when two identical "literals" are compared (as in line 21 above), they are again represented by the same memory location and pass the test, but fail when they are compared after assigning to variables (line 22-23).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment