[Python-Dev] PyObject_RichCompareBool identity shortcut
Robert Kern
robert.kern at gmail.com
Thu Apr 28 05:42:03 CEST 2011
On 2011-04-27 22:16 , Guido van Rossum wrote:
> On Wed, Apr 27, 2011 at 11:48 AM, Robert Kern<robert.kern at gmail.com> wrote:
>> On 4/27/11 12:44 PM, Terry Reedy wrote:
>>>
>>> On 4/27/2011 10:53 AM, Guido van Rossum wrote:
>>
>>>> Maybe we should just call off the odd NaN comparison behavior?
>>>
>>> Eiffel seems to have survived, though I do not know if it used for
>>> numerical
>>> work. I wonder how much code would break and what the scipy folks would
>>> think.
>>
>> I suspect most of us would oppose changing it on general
>> backwards-compatibility grounds rather than actually *liking* the current
>> behavior. If the behavior changed with Python floats, we'd have to mull over
>> whether we try to match that behavior with our scalar types (one of which
>> subclasses from float) and our arrays. We would be either incompatible with
>> Python or C, and we'd probably end up choosing Python to diverge from. It
>> would make a mess, honestly. We already have to explain why equality is
>> funky for arrays (arr1 == arr2 is a rich comparison that gives an array, not
>> a bool, so we can't do containment tests for lists of arrays), so NaN is
>> pretty easy to explain afterward.
>
> So does NumPy also follow Python's behavior about ignoring the NaN
> special-casing when doing array ops?
By "ignoring the NaN special-casing", do you mean that identity is checked
first? When we use dtype=object arrays (arrays that contain Python objects as
their data), yes:
[~]
|1> nan = float('nan')
[~]
|2> import numpy as np
[~]
|3> a = np.array([1, 2, nan], dtype=object)
[~]
|4> nan in a
True
[~]
|5> float('nan') in a
False
Just like lists:
[~]
|6> nan in [1, 2, nan]
True
[~]
|7> float('nan') in [1, 2, nan]
False
Actually, we go a little further by using PyObject_RichCompareBool() rather than
PyObject_RichCompare() to implement the array-wise comparisons in addition to
containment:
[~]
|8> a == nan
array([False, False, True], dtype=bool)
[~]
|9> [x == nan for x in [1, 2, nan]]
[False, False, False]
But for dtype=float arrays (which contain C doubles, not Python objects) we use
C semantics. Literally, we use whatever C's == operator gives us for the two
double values. Since there is no concept of identity for this case, there is no
cognate behavior of Python to match.
[~]
|10> b = np.array([1.0, 2.0, nan], dtype=float)
[~]
|11> b == nan
array([False, False, False], dtype=bool)
[~]
|12> nan in b
False
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-Dev
mailing list