4

I'm running:

Python 2.7.8 (default, Oct  6 2017, 09:25:50)
GCC 4.1.2 20070626 (Red Hat 4.1.2-14) on Linux 2

As per the documentation:

The operators is and is not test for object identity: x is y is True if and only if x and y are the same object.

To get an object's identity, we can use the id function.


If we open up a new REPL we can see that 300 and -6 have the same identity (on CPython, this means that both refer to the same memory address):

>>> id(300)
94766593705400
>>> id(-6)
94766593705400

Note that the actual values may differ from execution to execution, but they are always equal.

However, doing 300 is -6 yields False:

>>> 300 is -6
False

I have a couple of questions:

  • Why (and how) do 300 and -6 share the same identity?
  • If they do, why is 300 is -6 yielding False?
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
  • 1
    REPL reuses `IDs`. Try this and you'll understand: `print(id(300)) or print(id(-6)) or 300 is -6` – cs95 Dec 20 '17 at 13:25
  • 2
    Can't reproduce in Python 3 on Windows `Python 3.4.2 (v3.4.2:ab2c023a9432, Oct 6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> id(300) 7807344 >>> id(-6) 8757184 >>> id(300) 8757184 >>> id(-6) 8755376` – DeepSpace Dec 20 '17 at 13:25
  • However, it reproduces in Python 2 on Centos `Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> id(300) 15912616 >>> id(-6) 15912616 >>> id(300) 15912616` – DeepSpace Dec 20 '17 at 13:28
  • @cᴏʟᴅsᴘᴇᴇᴅ Do you have any source to back that up, by chance? – Matias Cicero Dec 20 '17 at 13:28
  • It's actually mentioned in the [docs](https://docs.python.org/3.3/library/functions.html#id)... "Two objects with non-overlapping lifetimes may have the same id() value." – cs95 Dec 20 '17 at 13:31
  • @cᴏʟᴅsᴘᴇᴇᴅ Thanks! Now it makes sense – Matias Cicero Dec 20 '17 at 13:33
  • 1
    It's also worth noting that Python caches inetegers in the range [-5, 256]: `>>> 6 is 6 True >>> -999 is -999 False` – DeepSpace Dec 20 '17 at 13:33

2 Answers2

10

After id(300) is executed, no more references to 300 exist, so the id is freed. When you execute id(6), it gets that same chunk of memory and stores 6 instead. When you do -300 is 6, -300 and 6 are both referenced at the same time, so they won't have the same address anymore.

If you keep references to both -300 and 6, this happens:

>>> a, b = -300, 6
>>> id(a)
some number
>>> id(b)
some different number; 6 is still in the other memory address.

Note: In CPython, numbers from -5 to 256 (I think) are cached, and will always have the same address, so this will not happen.

internet_user
  • 3,149
  • 1
  • 20
  • 29
8

This is documented behavior of the id() function:

Return the “identity” of an object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

The lifetime of an integer object in the sample code is just the function call (e.g. id(300)) as no other references to it exist.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378