2015-08-26 16 views
7

我想了解哪些項目可以在Python中以set成員資格進行測試。一般來說,設置成員資格測試的工作方式類似於Python中的list成員資格測試。是什麼讓一個元素有資格在Python中進行集合成員資格測試?

>>> 1 in {1,2,3} 
True 
>>> 0 in {1,2,3} 
False 
>>> 

但是,集合與列表不同,因爲它們不能包含不可對象,例如嵌套集合。

名單,好嗎:

>>> [1,2,{1,2}] 
[1, 2, {1, 2}] 
>>> 

組不工作,因爲unhashable:

>>> {1,2,{1,2}} 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'set' 
>>> 

現在,即使集不能是其他組的成員,我們可以使用它們在會員測試中。這樣的檢查不會導致錯誤。

>>> {1} in {1,2,3} 
False 
>>> {1,2} in {1,2,3} 
False 
>>> set() in {1,2,3} 
False 
>>> 

但是,如果我嘗試做當被測試的元件相同的測試是dict,我得到這表明,被測試的元素不能unhashable錯誤。

>>> {'a':1} in {1,2} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'dict' 
>>> {} in {1,2} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'dict' 
>>> 

那不可能是故事的全部,因爲set可以會員資格測試在另一組,即使它本身就是unhashable,給人一種結果,而不是一個錯誤。

所以問題是:是什麼讓一個元素有資格在Python中進行集合成員測試?

+1

呃,frozensets * *也不能容納unhashable項目 - 不同的是,它們本身可哈希 – jonrsharpe

+0

感謝您指出了這一點。它應該指的是冷凍集是一個可能的成員,但我的文本沒有反映出這一點。編輯相關評論。 – Forald

回答

6

您無法測試set中不可哈希元素的成員資格。示例 -

>>> [1,2] in {1,2} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 
>>> {1:2} in {1,2} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'dict' 

設置了可用於包含檢查的唯一不可哈希對象。正如在documentation -

注給出時,ELEM參數傳遞給__contains __(),刪除(),並丟棄()方法可以是一組。爲了支持搜索等效的凍結集,elem集在搜索過程中暫時發生變化,然後進行恢復。在搜索期間,elem集不應該被讀或者變異,因爲它沒有一個有意義的值。

爲了支持搜索具有與集合相同元素的frozensets,將集合臨時變爲frozenset()並進行比較。示例 -

>>> set([1,2]) in {1,2,frozenset([1,2])} 
True 
+0

有誰知道如何從python函數獲取該信息?我有以下幾點:>>> def f():{3,4}中的return set([1,2]),當我做f.func_code.co_consts時,我得到(None,1,2,5,6)但是不能只設置consts。我記得用python optimisations看過一個視頻,但我不記得這個人是如何設法將凍結集放到方法之外的。 – Har

+0

你使用Python 2.x嗎?在Python 3.4中,它會返回 - >>> >>> f .__ code __。co_consts (None,1,2,3,4,frozenset({3,4}))' –

+0

yes我使用的是2.7.10,不把{3,4}轉換成凍結的集合......或者它只是沒有顯示它,因爲它可能是一個運行時間的東西 – Har

7

令人困惑的是,當你說'如果在集合中設置',我認爲python將左手設置爲一個冷凝集,然後測試它。例如。

>>> f = frozenset({1}) 
>>> f 
frozenset([1]) 
>>> x = {f, 2, 3} 
>>> {1} in x 
True 

然而,沒有相當於frozenset爲一個字典,因此它不能在字典轉換爲成員資格測試不可變對象,並且因此它將失敗。

我不知道這是這裏遵循的「規則」 - 是否有或一些普通方法可以overrideen提供不可改變的轉換,如果這種行爲是硬編碼到一套一套的具體情況。

+2

正確的你是:https://hg.python.org/cpython/file/tip/Objects/setobject.c#l1892 –

+0

傑出,謝謝! – Forald