float('nan') == float('nan') returns False because it is designed to not to match with itself. That's why list.index() function is unable to find a match for NaN value and is raising ValueError exception.
Please read Why is NaN not equal to NaN? to know more about this behaviour.
Below is a custom function check_nan_match() to check whether passed objects are having same value or not. This function will be able to match for NaN objects too based on the above property i.e. NaNs return False when matched with itself.
# Function too check passed values are match, including `NaN`
def check_nan_match(a, b):
return (b != b and a != a) or a == b
# ^ ^ `NaN` property to return False when matched with itself
To get the index of tuple in the list containing NaN, here I am creating another custom function as get_nan_index. This function accepts my_list and my_tuple as param, iterates over the my_list to get the index of my_tuple. To check for the equality, I am using previously created check_nan_match function which is capable to match NaN values too.
# Get index from list of tuple , when tuple is passed
def get_nan_index(my_list, my_tuple):
for i, t in enumerate(my_list):
if all(check_nan_match(x, y) for x, y in zip(t, my_tuple)):
return i
else:
raise ValueError # Raise `ValueError` exception in case of no match.
# Similar to `list.index(...)` function
Sample run:
# check for tuple with `NaN`
>>> get_nan_index([('a', 7.0), ('b', float('nan'))], ('b', float('nan')))
1
# check for tuple without `NaN`
>>> get_nan_index([('a', 1), ('b', 2)], ('b', 2))
1
# `ValueError` exception if no match
>>> get_nan_index([('a', 7.0), ('b', 3)], ('b', float('nan')))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in get_nan_index
ValueError