2

注意: python3 中的代码示例,但问题也代表 python2(替换.keys.viewkeys等)

dict对象提供(有时)支持集合操作的视图方法:

>>> {'a': 0, 'b': 1}.keys() & {'a'}
{'a'}
>>> {'a': 0, 'b': 1}.items() & {('a', 0)}
{('a', 0)}

但是值视图不支持集合运算符:

>>> {'a': 0, 'b': 1}.values() & {0}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'set'

我知道一个 dict 值可以是一个不可散列的对象,因此并不总是可以创建一组值,但是对于 也是如此dict.items,并且这里的集合操作只会在运行时失败,因为.items一旦存在不可散列输入 dict,而 set 操作.values立即失败。

文档提到Values 视图不被视为 set-like 因为条目通常不是 unique,但这似乎不是一个令人信服的理由 - 例如,python 不会阻止您创建像{0, 0, 1, 2}.

这种行为不一致的真正原因是什么?

4

4 回答 4

3

如果我们视为一个集合,那么您将使值字典视图成为一个非常昂贵的对象来生成。您必须先计算所有值的哈希值,然后才能将其用作集合;您真的不想为大型字典执行此操作,尤其是如果您事先不知道所有值是否都是可散列的。

因此,将其保留为显式操作要好得多;如果要将值视为一个集合,请显式将其设为集合:

values = set(yourdict.values())

这种dict.items()行为源于我们预先知道键至少是唯一的,因此每个(键,值)对也是唯一的;在幕后,您可以将成员资格测试委托给键字典视图。

但是,一旦您对其使用集合操作(​​交集、联合等),您将创建一个set对象,而不是字典视图。对于这样的set对象,(键,值)对中的两个元素都必须是可散列的,因为泛型set类型不能对键做出相同的假设,您也不能保持该约束(这{'a': 0}.items() & {('a', 1)}是完全合法的,但会导致重复键)。

于 2014-07-18T18:21:33.180 回答
0

原因是它没有在dict_values类型中实现,或者因为dict_values该类明确禁止它。

由于您的值通常是非唯一的项目列表,因此将其转换为集合并不是一个好主意。如果您确实需要,只需手动转换它。我的假设是它是不允许的,因为它通常是一个坏主意,因为它可能导致数据丢失。

于 2014-07-10T13:47:09.513 回答
0

因为在 adict你不能有重复的keys值,但你可以有重复的values值:

>>> d = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
>>> d.keys()
[0, 1, 2, 3, 4]
>>> d.values()
[0, 0, 0, 0, 0]
>>> d.items()
[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)]

keys()方法返回类似于cuacks 和鸭子之类的东西,set因为你不能在 上重复键dict,但你可以在上重复值values()。这就是为什么keyscuacks 和 ducks 喜欢 set 而valuescuacks 和 ducks 喜欢list.

于 2014-07-10T13:43:42.807 回答
-2

如果你在 leetcode 中编码,那么你可以通过改变结果来实现

return res_dic.values()

return list(res_dic.values())
于 2019-06-17T13:10:46.120 回答