Rich Comparisons Gotcha
Robert Kern
robert.kern at gmail.com
Mon Dec 8 02:13:26 EST 2008
James Stroud wrote:
> Robert Kern wrote:
>> James Stroud wrote:
>>> py> 112 = [1, y]
>>> py> y in 112
>>> Traceback (most recent call last):
>>> File "<stdin>", line 1, in <module>
>>> ValueError: The truth value of an array with more than one element is...
>>>
>>> but not
>>>
>>> py> ll1 = [y,1]
>>> py> y in ll1
>>> True
>>>
>>> It's this discrepancy that seems like a bug, not that a ValueError is
>>> raised in the former case, which is perfectly reasonable to me.
>>
>> Nothing to do with numpy. list.__contains__() checks for identity with
>> "is" before it goes to __eq__().
>
> ...but only for the first element of the list:
>
> py> import numpy
> py> y = numpy.array([1,2,3])
> py> y
> array([1, 2, 3])
> py> y in [1, y]
> ------------------------------------------------------------
> Traceback (most recent call last):
> File "<ipython console>", line 1, in <module>
> <type 'exceptions.ValueError'>: The truth value of an array with more
> than one element is ambiguous. Use a.any() or a.all()
> py> y is [1, y][1]
> True
>
> I think it skips straight to __eq__ if the element is not the first in
> the list.
No, it doesn't skip straight to __eq__(). "y is 1" returns False, so (y==1) is
checked. When y is a numpy array, this returns an array of bools.
list.__contains__() tries to convert this array to a bool and
ndarray.__nonzero__() raises the exception.
list.__contains__() checks "is" then __eq__() for each element before moving on
to the next element. It does not try "is" for all elements, then try __eq__()
for all elements.
> That no one acknowledges this makes me feel like a conspiracy
> is afoot.
I don't know what you think I'm not acknowledging.
--
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-list
mailing list