float('nan') == float('nan') 返回False,因为它被设计为不与自身匹配。这就是为什么list.index() 函数无法找到匹配NaN 值并引发ValueError 异常的原因。
请阅读Why is NaN not equal to NaN?以了解有关此行为的更多信息。
下面是一个自定义函数check_nan_match(),用于检查传递的对象是否具有相同的值。这个函数也可以根据上面的属性匹配NaN对象,即NaNs在匹配自身时返回False。
# 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
为了在包含NaN 的list 中获取tuple 的索引,这里我创建了另一个自定义函数get_nan_index。此函数接受my_list 和my_tuple 作为参数,遍历my_list 以获得my_tuple 的索引。为了检查相等性,我使用了之前创建的 check_nan_match 函数,它也能够匹配 NaN 值。
# 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
示例运行:
# 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