Why Id Function Behaves Differently With Integer And Float?
Solution 1:
That is because the result of id
in numeric constants is implementation defined.
In your case, Python 2.7.2, IIRC, the issue is that the compiler builds a few useful integer constants as singletons, (from -1 to 100 or so). The rationale is that these numbers are used so frequently that it makes no sense to dynamically allocate them each time they are needed, they are simply reused.
But that constant singleton optimization is not useful for float
values, other than maybe 0.0, there are too many of them! So each time a new float
value is needed it is allocated, and it gets a different id.
For a more deeply insight, read the source! This file is from Python3, but the idea is the same: look for the small_ints
array.
Solution 2:
id
is never really predictable, not even for integers. With low the very integers 2 and 4, you just happen to hit the small integer cache. Try this:
>>>a = 12345>>>b = 12345>>>id(a)
33525888
>>>id(b)
33525852
>>>
Solution 3:
For small integers and strings, that are expected to be frequently used, Python uses internal memory optimization. Since any variable in Python is a reference to memory object, Python puts such small values into the memory only once. Then, whenever the same value is assigned to any other variable, it makes that variable point to the object already kept in memory. This works for strings and integers as they are immutable and if the variable value changes, effectively it's the reference used by this variable that is changed, the object in memory with original value is not itself affected.
That's why variables foo1 and foo2 in first case hold reference to the same integer object in memory with value 4 and therefore the ids are the same.
First of all, floating point numbers are not 'small', and, second, the same 4.3 in memory depending on calculations might be kept as 4.3123456789 and 4.31239874654 (just example numbers to explain). So these two values are two different objects, but during calculations and displaying the meaningful part looks the same, i.e. 4.3 (in fact there's obviously many more possible values in memory for the same meaningful floating point number). So reusing the same floating point number object in memory is problematic and doesn't worth it after all.
That's why in the second case foo1 and foo2 reference different floating point object in memory and therefore have different ids.
See more details on how floating point numbers are kept in memory:
http://docs.python.org/2/tutorial/floatingpoint.html
Also, there's a big article on floating point numbers at Oracle docs.
@josliber, I edited the answer before reposting as you advised.
Solution 4:
Besides from the mentionned (and very true) reasons, did you verify if foo1 == foo2
at the first place? As you are dealing with floating point values, there can very easily be differences...
Solution 5:
For floating numbers, 1.0+3.3 == 4.3 is not always TRUE (in Python or other languages). and mutable objects with same value can have different IDs, too.
Post a Comment for "Why Id Function Behaves Differently With Integer And Float?"