Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens behind the scenes when python adds small ints? [duplicate]

Tags:

I was fiddling around with id recently and realized that (c?)Python does something quite sensible: it ensures that small ints always have the same id.

>>> a, b, c, d, e = 1, 2, 3, 4, 5 >>> f, g, h, i, j = 1, 2, 3, 4, 5 >>> [id(x) == id(y) for x, y in zip([a, b, c, d, e], [f, g, h, i, j])] [True, True, True, True, True] 

But then it occurred to me to wonder whether the same is true for the results of mathematical operations. Turns out it is:

>>> nines = [(x + y, 9) for x, y in enumerate(reversed(range(10)))] >>> [id(x) == id(y) for x, y in nines] [True, True, True, True, True, True, True, True, True, True] 

Seems like it starts failing at n=257...

>>> a, b = 200 + 56, 256 >>> id(a) == id(b) True >>> a, b = 200 + 57, 257 >>> id(a) == id(b) False 

But sometimes it still works even with larger numbers:

>>> [id(2 * x + y) == id(300 + x) for x, y in enumerate(reversed(range(301)))][:10] [True, True, True, True, True, True, True, True, True, True] 

What's going on here? How does python do this?

like image 475
jsau Avatar asked May 23 '11 18:05

jsau


People also ask

Are integers Singletons in Python?

We have established that Python indeed is consuming smaller integers through their corresponding singleton instances, without reallocating them every time. Now we verify the hypothesis that Python indeed saves a bunch of allocations during its initialization through these singletons.

Is operator for integers in python?

Using the + Operator in Python The + operator in Python is used for addition – at least when it is used on integers or floating-point numbers. When used on strings it does something else entirely.


1 Answers

You've fallen into a not uncommon trap:

id(2 * x + y) == id(300 + x) 

The two expressions 2 * x + y and 300 + x don't have overlapping lifetimes. That means that Python can calculate the left hand side, take its id, and then free the integer before it calculates the right hand side. When CPython frees an integer it puts it on a list of freed integers and then re-uses it for a different integer the next time it needs one. So your ids match even when the result of the calculations are very different:

>>> x, y = 100, 40000 >>> id(2 * x + y) == id(300 + x) True >>> 2 * x + y, 300 + x (40200, 400) 
like image 90
Duncan Avatar answered Oct 11 '22 18:10

Duncan