dict.items() 对不可哈希值的“设置类似”行为

'Set like' behaviour of dict.items() for non hashable values

提问人:Evan Benn 提问时间:11/1/2023 更新时间:11/1/2023 访问量:48

问:

https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects

文档说:

如果所有值都是可散列的,因此(键、值)对是唯一且可散列的,则项目视图也是类似集合的。

但是,不可散列的项目(列表)似乎确实支持“类似集合”的操作:

> {1:2, 3:4}.items() >= {1:2}.items()
True
> {1:[2], 3:4}.items() >= {1:[2]}.items()
True
> set({1:[2], 3:4}.items())
TypeError: unhashable type: 'list'

为什么这样做?可以依靠此行为正常工作吗?我没有找到不正常的列表。

python 字典

评论

1赞 STerliakov 11/1/2023
我不明白你的问题是什么。Dict 项目支持类似集合的操作,是的,但它们不是集合。你不能在一个集合中有任何不可哈希的东西(而且在项目中带有列表的元组是不可哈希的)。当然,您可以在字典中拥有不可哈希的值,这不会重新进行“类集合”操作。当然,效率不同:从不使用任何哈希值,因此您的哈希值是通过一堆比较来执行的,而没有先前基于哈希值的调度。你可以用 s in 定义你的类,看看到底发生了什么。dict.items>=print__hash____eq__
1赞 STerliakov 11/1/2023
tio.run/...

答:

1赞 Blckknght 11/1/2023 #1

我认为文档的第二个是不正确的。字典视图的行为始终类似于一个集合,因为它的内容是唯一的。我们知道情况是这样,因为所有键都是唯一的,并且项始终是包含键的 2 元组。实现不需要对元组的值部分进行哈希处理,对键进行哈希处理就足以有效地执行所有操作。itemsset

评论

0赞 Evan Benn 11/1/2023
谢谢,这是否意味着设置操作只检查密钥?或者他们首先检查键,然后对值执行 a(而不是对键值对的哈希值执行 a?.items====
0赞 Blckknght 11/1/2023
每个查找键(使用其哈希值)的 dict 操作也会检查找到的条目是否与键匹配,因为哈希冲突是可能的。对于项目视图,我很确定它会比较元组的两个部分(在仅使用键的哈希值进行初始查找之后)。
0赞 STerliakov 11/3/2023
@EvanBenn,您可以将两个 dictitem 的子集可视化为“设置键的并集(哈希,然后是公共元素),然后比较相应的值 - 其中键和值都相等,将这对包含到交集中。这与元组集的过程不同:值不包含在哈希中,因为键几乎已经形成了一个集合。__eq____eq__