>>> li = [2, [3, 4]]
>>> 3 in li
False
>>> {2, {3, 4}}
TypeError: unhashable type: 'set'
为什么在Python(2.x和3.x)中没有实现嵌套(在数学中使用)?
答案 0 :(得分:18)
已实施,但您需要使用hashable type。 frozenset()
就是那种类型。文档甚至告诉你:
要表示集合集,内部集合必须是
frozenset
个对象。
演示:
>>> {2, frozenset([3, 4])}
set([frozenset([3, 4]), 2])
这是因为常规set()
是 mutable ,这与用于集合(和字典)的数据结构的要求不兼容;这些需要稳定的对象,当根据它们的哈希值用作表中的键时可以重新定位。
再次提供文件:
set
类型是可变的 - 可以使用add()
和remove()
等方法更改内容。由于它是可变的,因此它没有哈希值,不能用作字典键或另一组的元素。frozenset
类型是不可变的, hashable - 其内容在创建后无法更改;因此,它可以用作字典键或另一组的元素。
答案 1 :(得分:0)
正如@Martin Pieters所提到的,如果使用frozenset对象而不是常规集,则可以使用,因为frozenset对象是可清除的。
原因是因为python(list,dict,set,...)的普通容器是可变的,这意味着它们可以在其生命周期中改变(一个元素可能被添加到一个集合中)。 mutable数据类型不能是hashable(因为hashable基本上意味着“识别具有唯一编号(= hash)的不可变对象)。
frozenset对象是可散列的,这意味着它们可以在集合中使用,这是因为在创建冻结集后不再能够更改冻结集(冻结集没有可用的update()方法)。这意味着如果要更改嵌套在集合中的冻结集,则必须从冻结集创建新集,对该集进行更改,删除旧冻结集并将新集转换为冻结集并添加它(这看起来很复杂,如果这很难理解,请告诉我。)
集合只能由可散列对象组成的原因与集合中的每个对象必须对该集合唯一的事实有关,并且python通过使用对象的散列来检查它,因为这是有效的并且安全地做到这一点。