我試圖比較包含nan
的python中的兩個集合,但由於{float('nan')} != {float('nan')}
而苦苦掙扎。例如:在python中比較包含nan的集合
s1 = {float('nan'), 1}
s2 = {float('nan'), 1, 2}
assert set.issubset(s1, s2)
我得到一個斷言錯誤。我該如何處理?
我試圖比較包含nan
的python中的兩個集合,但由於{float('nan')} != {float('nan')}
而苦苦掙扎。例如:在python中比較包含nan的集合
s1 = {float('nan'), 1}
s2 = {float('nan'), 1, 2}
assert set.issubset(s1, s2)
我得到一個斷言錯誤。我該如何處理?
您也可以爲此編寫一個簡單的函數。請注意,float('nan') == float('nan')
對於nan
是False;要檢查是否有任何元素是nan,我們只需要將其與自身進行比較。
def is_subset(s1, s2):
no_nan_set = lambda s: {x for x in s if x == x}
s1_nan, s2_nan = no_nan_set(s1), no_nan_set(s2)
if s1_nan != s1 and s2_nan != s2:
return s1_nan.issubset(s2_nan)
elif s1_nan == s1 and s2_nan == s2:
return s1.issubset(s2)
else:
return False
可以簡化if-elif-else
塊
def is_subset(s1, s2):
no_nan_set = lambda s: {x for x in s if x == x}
s1_nan, s2_nan = no_nan_set(s1), no_nan_set(s2)
return (s1_nan != s1 and s2_nan != s2 and s1_nan.issubset(s2_nan)) \
or (s1_nan == s1 and s2_nan == s2 and s1.issubset(s2))
注意,如果只將您所設定的有兩個或兩個以上nan
S(因爲float('nan') != float('nan')
),這將正常工作,同樣將工作好嗎如果nan
的id
s不同。最後,即使您在一套或兩套中都沒有nan
,這也可以工作。
刪除所有nan
值來創建臨時集,然後對其進行比較。之後,分別處理nan
比較。例如,您可以檢查兩個原始集合是否包含nan
。
即使您可以在沒有聲明異常的情況下執行比較,float('nan') == float('nan')
也會返回False
,因此從該組比較中獲得的價值很小(這會使比較的其餘部分無效)。您可以通過打印set.issubset
來檢查此行爲。
s1 = frozenset({float('nan'), 1})
s2 = frozenset({float('nan'), 1, 2})
print frozenset.issubset(s1,s2)
其中打印False
。
雖然set
is deprecated,您可以生成臨時設置如下:
s3 = set([value for value in s1 if not math.isnan(value)])
(根據需要重複每個臨時設置)
一旦它已經在集合中,我怎樣才能從集合中刪除nan? – user1507844 2014-11-13 01:00:33
@ user1507844:['sets'已棄用](https://docs.python.org/2/library/sets.html)。但是,如果你不能使用'set.remove'來完成這個,你可以很容易地生成不包含'nan'的新集合,並使用'set.issubset'。例如,'s3 = set([如果不是math.isnan(value)]),將會在s1中生成一個新的'set',其中包含所有不等於'nan'的值。我也編輯了這個評論到我原來的帖子,以防這裏的語法令人困惑。 – grovesNL 2014-11-13 02:23:02
創建一個新的集合可能是最簡單的...只是不知道math.isnan。謝謝! – user1507844 2014-11-13 19:32:28
一種方法:身份平等(見文檔here前測試,例如),因此,如果您使用相同nan
它會工作:
>>> nan = float("nan")
>>> s1 = {nan, 1}
>>> s2 = {nan, 1, 2}
>>> set.issubset(s1, s2)
True
即使
>>> s1 = {float("nan"), 1}
>>> s2 = {float("nan"), 1, 2}
>>> set.issubset(s1, s2)
False
與nan
s工作是不夠的尷尬,我會盡量避免將它們放在集和切換到不同的規範形式。但你總是可以確定它是同一個:
>>> def one_nan(x, nan=float("nan")):
... return nan if math.isnan(x) else x
...
>>> set.issubset(set(map(one_nan, s1)), set(map(one_nan, s2)))
True
或千變異。 (我有時使用x != x
作爲nan-detection的快捷方式,但在此處可能是個好主意。)
我無法控制它是否在設定中結束或不幸... – user1507844 2014-11-13 01:01:21
你在s2中左括號??? – Hackaholic 2014-11-08 02:35:46
是的,對不起。固定 – user1507844 2014-11-08 02:37:39
@ user1507844:請說明「我該如何處理這個」的含義。你想要發生什麼? – unutbu 2014-11-08 02:46:15