2014-05-06 35 views
2
>>> li = [2, [3, 4]] 
>>> 3 in li 
False 

>>> {2, {3, 4}} 
TypeError: unhashable type: 'set' 

爲什麼設置嵌套(在數學中使用)沒有在Python(2.x和3.x)中實現?爲什麼設置嵌套不在Python中實現?

+0

請注意,即使您使用'frozensets',您仍然無法期望'li'中有3個工作。您將不得不逐個檢查每個子集/子列表。 – msvalkon

+1

集合僅包含唯一元素,因此使用散列來確定相等性。集不可哈希,因爲他們是可變的:http://stackoverflow.com/questions/14193438/are-python-sets-mutable – CoDEmanX

+0

@msvalkon:我甚至不喜歡'3在李'返回'真正' 。因爲那是對數學表達的不同評估。 – Bentley4

回答

17

它已實施,但您需要使用hashable type代替。 frozenset()是那種類型。該文檔甚至告訴您如此:

要表示套集,內部集必須是frozenset對象。

演示:

>>> {2, frozenset([3, 4])} 
set([frozenset([3, 4]), 2]) 

這是因爲常規set()可變,這是與用於集(和字典)數據結構的的要求不相容;這些需要穩定的對象,當它們用作基於哈希表的表中的鍵時可以重新定位。

的再次文檔:

set類型是可變的 - 內容能夠使用像add()remove()方法來改變。由於它是可變的,因此它沒有散列值,不能用作字典鍵或另一個集的元素。 frozenset類型是不可改變的,可散列 - 其內容在創建後不能更改;因此它可以用作字典鍵或另一組元素。

+0

鑑於Python開發人員想要設置爲可變的,這就解釋了爲什麼必須創建冷凍集類型。涼! – Bentley4

0

正如@Martin Pieters所提到的,如果您使用frozenset對象而不是常規集合,因爲frozenset對象是可哈希的。

原因是因爲python(list,dict,set,...)的普通容器是可變的,這意味着它們可以在其生命週期中改變(一個元素可能被添加到一個集合中)。可變數據類型不可哈希(因爲可哈希基本上意味着「用唯一編號(=散列)標識不可變對象)。

frozenset對象是可散列的,這意味着它們可以成組使用,這是以成本在凍結集創建後不再能夠改變凍結集(這個方法沒有updateset()方法可用於凍結集)這意味着如果你想改變集合中嵌套的凍結集,你必須創建一個新集凍結的設置,對該設置進行更改,刪除舊的凍結集並將新集轉換爲凍結集並添加它(這看起來很複雜,如果這很難理解,請告訴我)

爲什麼設置只能包含可哈希對象與集合中的每個對象都必須處理的事實有關對於該集合來說是唯一的,python通過使用對象的哈希來檢查它,因爲這是一種高效且安全的方法。

相關問題