注意: 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
也是如此,而这里是集合只有在dict 中存在不可用类型时,.items
才会在运行时失败,而.values
的设置操作会立即失败。
文档提到Values views are not treated as set-like since the entries are generally not unique,但这似乎并不是一个令人信服的理由 - 例如,python不会阻止您创建像{0, 0, 1, 2}
这样的集合文字。
这种行为不一致的真正原因是什么?
答案 0 :(得分:3)
如果我们 将值视为一个集合,那么您将使值字典视图成为一个非常昂贵的对象。您必须先计算所有值的哈希值,然后才能将其用作集合;你真的不想为一本大字典做这件事,特别是如果你不知道所有的价值是否可以清洗。
因此,这最好留作明确的操作;如果您想将值视为一个集合,显式使其成为一个集合:
values = set(yourdict.values())
dict.items()
行为源于这样一个事实:我们事先知道密钥至少是唯一的,因此每个(密钥,值)对也是唯一的;在封面下,您可以将成员资格测试委托给密钥字典视图。
但是只要你对它(交集,联合等)使用set操作,你就会创建一个 new set
对象,而不是字典视图。对于这样的set
对象,(key,value)对中的两个元素必须是可散列的,因为泛型set
类型不能对键做出相同的假设,也不能你能保持这种约束吗(因为{'a': 0}.items() & {('a', 1)}
是完全合法的,但会导致重复的密钥)。
答案 1 :(得分:0)
因为在dict
中,您不能重复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 and ducks之类的内容,例如set
,因为dict
上没有重复键,但您可以在{{1}上重复显示值}}。这就是为什么values()
像keys
一样诅咒和躲避values
诅咒和像list
一样的鸭子。
答案 2 :(得分:0)
原因是它没有在dict_values
类型中实现,或者因为dict_values
类明确禁止它。
由于您的值通常是一个非唯一的项目列表,因此将其转换为集合并不是一个好主意。如果你想要,只需手动转换它。我的假设是它被禁止,因为它通常是一个坏主意,因为它可能导致数据丢失。
答案 3 :(得分:-2)
如果使用leetcode编码,则可以通过更改
的结果来实现return res_dic.values()
到
return list(res_dic.values())