我有一个实现myClass__hash__的类(我们称之为__eq__)。我也有一个dict,它将myClass对象映射到某个值,计算需要一些时间。

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

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

这是我的问题:

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

后续问题:

我想最小化dict中的条目数,因此,理想情况下,我只想在myClass中保留一组等效的dict对象中的一个。再次如此,似乎在计算__eq__时需要调用if myNewClassObj in dict,这会将dict的O(1)查找时间file污为O(n)查找时间

最佳答案

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

如果在字典中找到一些具有相同__hash__的对象,则将在每个对象上调用__eq__。如果__eq__对任何一个求值均相等,则myNewMyClassObj in dict_返回True。

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

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

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

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

10-16 22:21