我有一个实现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/