使用union向“set()”添加词典

2024-04-28 01:17:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚碰到一件有趣的事,我想我会问的。

将字典添加到set时,我假设字典将作为完整字典添加,而不是。只添加键:

dicty = {"Key1": "Val1", "Key2": "Val2"}
setunion = set()
setunion.union(dicty)
=> set(['Key2', 'Key1'])

当您试图使用set.add()添加时,会得到一个错误:

setadd = set()
setadd.add(dicty)
Traceback (most recent call last):
  File "python", line 1, in <module>
TypeError: unhashable type: 'dict'

显然,这种行为与列表有很大不同:

   listy = []
   listy.append(dicty)
   listy
=> [{'Key2': 'Val2', 'Key1': 'Val1'}]

In the docs它说集合是可散列对象的无序集合,这暗示了上面的一些问题。

问题

怎么回事?集合项必须是散列的,很明显,这与我为什么只使用.union()将键添加到集合有关,但是为什么使用.add()会出错?

列表中集合行为的差异背后是否有可用性的原因?

Python(或库)中是否有一个数据类型本质上像列表一样工作,但只保留唯一的项?


Tags: add列表字典错误key2key1unionset
2条回答

不,根据定义那是不可能的。哈希表(如dicts和sets)进行查找的方式与数组(如list)进行查找的方式基本上是唯一的。逻辑错误是,如果您的数据类型只保存重复项,那么如果您将其中一个元素变异为非唯一的,会发生什么情况?

a, b = [0], [0, 1]
s = SpecialSet(a, b)
a.append(1)  # NOW WHAT?!

如果要将字典添加到集合,可以添加该集合的dict.items视图(实际上只是元组列表),但必须先转换为元组。

a = {1:2, 3:4}
s = set()
s.add(tuple(a.items()))

那你就得在它离开片场后重新录音才能把字典拿回来

for tup in s:
    new_a = dict(tup)

PEP416中提出了一个内置的frozendict类型,但最终被拒绝。

使用set.union(),要求将方法的参数的元素添加到集合,而不是对象本身。在字典上迭代可以得到键。如果在列表、元组或字符串上使用set.union(),则会得到类似的结果,这些内容中的内容会添加到集合中:

>>> s = {42}
>>> s.union('foo')
set([42, 'o', 'f'])

添加了单个字符串'o''f',而不是字符串'foo'

不能将字典添加到集合,因为它们是可变的;集合只支持存储可散列对象,并且对象是可散列的要求之一是它们是不可变的。

相关问题 更多 >