python - 当你调用 `if key in dict` 时会发生什么

标签 python hash dictionary equality

我有一个实现了 __hash____eq__ 的类(我们称它为 myClass)。我还有一个 dictmyClass 对象映射到某个值,计算需要一些时间。

在我的程序中,许多(数以百万计)myClass 对象被实例化。这就是我使用 dict 来跟踪这些值的原因。

但是,有时新的 myClass 对象可能等同于旧的对象(由 __eq__ 方法定义)。因此,与其再次计算该对象的值,不如在 dict 中查找旧的 myClass 对象的值。为此,我执行 if myNewMyClassObj in dict

这是我的问题:

当我使用 in 子句时,调用的是什么,__hash____eq__?使用 dict 的要点是它的查找时间为 O(1)。那么 __hash__ 必须被调用。但是如果 __hash____eq__ 不是等价的方法呢?在那种情况下,我会得到一个误报吗 if myNewMyClassObj in dict

跟进问题:

我想尽量减少 dict 中的条目数,因此理想情况下,我希望在 中只保留一组等效的 myClass 对象中的一个字典。因此,在计算 if myNewClassObj in dict 时,似乎需要调用 __eq__,这会破坏 dict 的 O(1)查找时间到 O(n) 查找时间

最佳答案

首先,__hash__(myNewMyClassObj) 被调用。如果在字典中没有找到具有相同散列值的对象,Python 会假定 myNewMyClassObj 不在字典中。 (请注意,Python 要求每当 __eq__ 对两个对象的计算结果相等时,它们的 __hash__ 必须相同。)

如果在字典中找到一些具有相同__hash__ 的对象,则对每个对象调用__eq__。如果 __eq__ 对它们中的任何一个计算为相等,则 dict_ 中的 myNewMyClassObj 返回 True。

因此,您只需要确保 __eq____hash__ 都很快。

对于您的后续问题:是的,dict_ 仅存储一组等效的 MyClass 对象(由 __eq__ 定义)中的一个。 (和设置一样。)

请注意,__eq__ 仅在具有相同散列并分配到相同存储桶的对象上调用。此类对象的数量通常很少(dict 实现确保了这一点)。所以你仍然有(大致)O(1) 查找性能。

关于python - 当你调用 `if key in dict` 时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13001913/

相关文章:

python - 如何在 python OpenCV 3 中对图像的特定区域进行图像处理?

java - 使用 hashCode 获取数组 java 元素的索引

Python dict 如何在一行中创建 key 或更新 key ?

ruby - 如何在 Ruby 中创建/提取变量/哈希到当前绑定(bind)中?

.net - 160 位 SHA1 散列的前 32 位是否可以替代 CRC32 散列?

swift - 在 Swift 4 中使用索引进行映射/归约

python - 使用多个值标准获取嵌套字典的键

python - 从具有字典名称的列表中迭代字典

python - 音频中的环形缓冲区

python - 服务 'web' 无法构建,协议(protocol)错误