Python Automatically Simplifies Floats To Ints During Set Construction
Solution 1:
>>> 1 == 1.0True>>> hash(1) == hash(1.0)
True
Python considers both to be exactly the same value with respect to use in sets and as a mapping key. The only way around this would be to wrap both values in a custom class that evaluates either of the above comparisons as false.
Solution 2:
Hint:
>>>a = 1>>>b = 1.00>>>a.__hash__()
1
>>>b.__hash__()
1
Solution 3:
I would think of this as a set of two distinct elements, a float 1.00 and an int 1.
That is your problem. Python thinks of them as one element, the number one. Whether this number is represented as a float or int doesn't change the fact that it is the same number.
Solution 4:
I am wondering if anyone can explain what is actually going on? Is there a way around this?
The explanations given should be sufficient. The simplest way around it that I can see is, if you're getting this input from the user, to not convert it to numeric form before storing it in the set.
A more complex way would be to store the entry as a tuple of (value, type): {(1, int), (1, float)}
, but this seems completely insane to me.
I would suggest you think long and hard before making a distinction between two numbers which are equal, based on the form of the representation that the user provides.
Solution 5:
As other answers have explained, since (int)1 and (float)1.0 have the same hash and test as equals, they are the same thing, as far as the Set is concerned.
Sometimes a language/standard-library will have an IdentitySet
class for collecting exact objects (by 'identity') rather than equality.
An answer on another question – https://stackoverflow.com/a/16994637/130288 – shows a small IdentitySet
implementation for Python. It wraps inserted objects in another class, Ref
, to force identity-comparisons – roughly as Ignacio's answer suggests.
Post a Comment for "Python Automatically Simplifies Floats To Ints During Set Construction"