Velocity Reviews > a.index(float('nan')) fails

# a.index(float('nan')) fails

Thomas Rachel
Guest
Posts: n/a

 10-27-2012
Am 27.10.2012 06:48 schrieb Dennis Lee Bieber:

> I don't know about the more modern calculators, but at least up
> through my HP-41CX, HP calculators didn't do (binary) "floating
> point"... They did a form of BCD with a fixed number of significant
> /decimal/ digits

Then, what about sqrt(x)**2 or arcsin(sin(x))? Did that always return
the original x?

Thomas

Nobody
Guest
Posts: n/a

 10-27-2012
On Thu, 25 Oct 2012 22:04:52 -0400, Terry Reedy wrote:

> Containment of nan in collection is tested by is, not ==.

AFAICT, it isn't specific to NaN. The test used by .index() and "in"
appears to be equivalent to:

def equal(a, b):
return a is b or a == b

IOW, it always checks for object identity before equality.

Replacing NaN with an instance of a user-defined class with a
non-reflexive __eq__() method supports this:

> class Foo(object):

= def __eq__(self, other):
= return False
=
> a = Foo()
> b = Foo()
> a in [1,2,a,3,4]

True
> b in [1,2,a,3,4]

False
> [1,2,a,3,4].index(a)

2
> [1,2,a,3,4].index(b)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: <__main__.Foo object at 0x7fa7055b0550> is not in list

Nobody
Guest
Posts: n/a

 10-27-2012
On Sat, 27 Oct 2012 08:56:16 +0200, Thomas Rachel wrote:

> Am 27.10.2012 06:48 schrieb Dennis Lee Bieber:
>
>> I don't know about the more modern calculators, but at least up
>> through my HP-41CX, HP calculators didn't do (binary) "floating
>> point"... They did a form of BCD with a fixed number of significant
>> /decimal/ digits

>
> Then, what about sqrt(x)**2 or arcsin(sin(x))? Did that always return
> the original x?

I'd be impressed if it managed the latter, i.e. arcsin(sin(0))==0 while
arcsin(sin(pi))==pi

Dennis Lee Bieber
Guest
Posts: n/a

 10-27-2012
On Sat, 27 Oct 2012 08:56:16 +0200, Thomas Rachel
<(E-Mail Removed)>
declaimed the following in gmane.comp.python.general:

> Am 27.10.2012 06:48 schrieb Dennis Lee Bieber:
>
> > I don't know about the more modern calculators, but at least up
> > through my HP-41CX, HP calculators didn't do (binary) "floating
> > point"... They did a form of BCD with a fixed number of significant
> > /decimal/ digits

>
> Then, what about sqrt(x)**2 or arcsin(sin(x))? Did that always return
> the original x?
>

The HPs probably not -- since they truncated at the decimal digit
level. The models with guard digits might have displayed the original,
as they used the guard digits to round results back up the display/entry
width (and to handle the infamous repeated addition of small amounts
<G>)
--
Wulfraed Dennis Lee Bieber AF6VN
http://www.velocityreviews.com/forums/(E-Mail Removed) HTTP://wlfraed.home.netcom.com/

Guest
Posts: n/a

 10-27-2012
On Thu, Oct 25, 2012 at 9:04 PM, Terry Reedy <(E-Mail Removed)> wrote:
> On 10/25/2012 9:46 PM, (E-Mail Removed) wrote:
>>>>>
>>>>> a = [float('nan'), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>>> a

>>
>> [nan, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>>>>
>>>>> a.index(float('nan'))

>>
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> ValueError: list.index(x): x not in list
>>
>> That means, the function .index() cannot detect nan values.
>> It happens on both Python 2.6 and Python 3.1
>>
>> Is this a bug? Or I am not using .index() correctly?

>
>
> It is a consequence of the following, which some people (but not all)
> believe is mandated by the IEEE standard.
>
>>>> nan = float('nan')
>>>> nan is nan

> True

It should be noted, for the record, that "nan is nan" returning True
has nothing to do with the concept of numbers or the IEEE standard and
is purely a consequence that Python runs on hardware with memory

>>>> nan == nan

> False

Here, equality, IS about number and this is appropriate and conforms
to the IEEE standard.

>>>> nanlist = [nan]
>>>> nan in nanlist

> True
>>>> nanlist.index(nan)

> 0

Here you just see an phenomenon with the python object/reference
model, which, being as it is, has nothing to do with numbers. This is
an area which, potentially could be changed in Python without
violating the IEEE standard whatsoever.

Mark

Ethan Furman
Guest
Posts: n/a

 10-28-2012
Steven D'Aprano wrote:
> The list.index method tests for the item with equality. Since NANs are
> mandated to compare unequal to anything, including themselves, index
> cannot match them.

This is incorrect. .index() uses identity first, then equality, and
will match the same NaN in a list. The OP's problem was in using a
different NaN.

Having said that, your find_nan() solution is probably the one to use
anyway.

> from math import isnan
>
> def find_nan(seq):
> """Return the index of the first NAN in seq, otherwise None."""
> for i, x in enumerate(seq):
> if isnan(x):
> return i
>
>
> For old versions of Python that don't provide an isnan function, you can
> do this:
>
> def isnan(x):
> return x != x