25

In my for loop, my code generates a list like this one:

list([0.0,0.0]/sum([0.0,0.0]))

The loop generates all sort of other number vectors but it also generates [nan,nan], and to avoid it I tried to put in a conditional to prevent it like the one below, but it doesn't return true.

nan in list([0.0,0.0]/sum([0.0,0.0]))
>>> False

Shouldn't it return true?

enter image description here

Libraries I've loaded:

import PerformanceAnalytics as perf
import DataAnalyticsHelpers
import DataHelpers as data
import OptimizationHelpers as optim
from matplotlib.pylab import *
from pandas.io.data import DataReader
from datetime import datetime,date,time
import tradingWithPython as twp
import tradingWithPython.lib.yahooFinance as data_downloader # used to get data from yahoo finance
import pandas as pd # as always.
import numpy as np
import zipline as zp
from scipy.optimize import minimize
from itertools import product, combinations
import time
from math import isnan
user1234440
  • 22,521
  • 18
  • 61
  • 103
  • 3
    This isn't a valid code - it should give an error because you can't divide list by float. – sashkello Dec 02 '13 at 02:16
  • works on mine, and returns false. Anaconda 2.7.3 Python – user1234440 Dec 02 '13 at 02:17
  • Are you sure you see this before loading any libraries? Because in standard Python 2.7 this is an illegal operation. As well as NaN which could only come from some `from ... import *`. It may be the feature of your interpreter, so please add this information to the question. – sashkello Dec 02 '13 at 02:22
  • In addition to my point, `numpy.nan in [numpy.nan, numpy.nan]` returns true as it should. I don't know where your nan comes from - I guess it is some library you are loading, because it is not a standard Python feature. – sashkello Dec 02 '13 at 02:26
  • i understand what you mean and I agree. Do you see any libraries that i've loaded that causes this. The first 4 libraries are custom libraries and they themselves load the same thing. – user1234440 Dec 02 '13 at 02:29
  • OK, so, your `nan` comes from matplotlib.pylab (just as a note, never ever use from ... import * because you will get stuff confused between libraries very easily. It is considered bad practice). Again, for me it returns true in such case, as it should. I still don't get why did your list division worked though... Because it shouldn't work like this for ordinary list or numpy array. – sashkello Dec 02 '13 at 02:33

3 Answers3

37

I think this makes sense because of your pulling numpy into scope indirectly via the star import.

>>> import numpy as np
>>> [0.0,0.0]/0
Traceback (most recent call last):
  File "<ipython-input-3-aae9e30b3430>", line 1, in <module>
    [0.0,0.0]/0
TypeError: unsupported operand type(s) for /: 'list' and 'int'

>>> [0.0,0.0]/np.float64(0)
array([ nan,  nan])

When you did

from matplotlib.pylab import *

it pulled in numpy.sum:

>>> from matplotlib.pylab import *
>>> sum is np.sum
True
>>> [0.0,0.0]/sum([0.0, 0.0])
array([ nan,  nan])

You can test that this nan object (nan isn't unique in general) is in a list via identity, but if you try it in an array it seems to test via equality, and nan != nan:

>>> nan == nan
False
>>> nan == nan, nan is nan
(False, True)
>>> nan in [nan]
True
>>> nan in np.array([nan])
False

You could use np.isnan:

>>> np.isnan([nan, nan])
array([ True,  True], dtype=bool)
>>> np.isnan([nan, nan]).any()
True
DSM
  • 342,061
  • 65
  • 592
  • 494
11

You should use the math module.

>>> import math
>>> math.isnan(item)
samrap
  • 5,595
  • 5
  • 31
  • 56
  • 5
    `math.isnan` expects a `float`, not an iterable. If you insist in using `math` you should do `any([math.isnan(x) for x in items])`. Note though that `numpy` should be much faster. – Raf Apr 16 '19 at 09:21
  • @Raf you were right. I was using bar charts with no bottom bar in the iteration that broke. I had to insert a white, hidden bar, save the SVG, then try again with the above code and it worked. Thanks! – Dance Party Jul 31 '19 at 23:54
4

May be this is what you are looking for...

a = [2,3,np.nan]
b = True if True in np.isnan(np.array(a)) else False
print(b)