如何在Python中实现Frozenset相等性?

时间:2019-06-10 03:36:42

标签: python cpython frozenset

在CPython中如何实现Frozenset相等性?特别是,我想知道fronzenset中的各个元素如何相互比较以及它们的总时间复杂度。

我看了set and frozenset difference in implementationhttps://stackoverflow.com/a/51778365/5792721

第二个链接中的答案涵盖了比较集合中各个元素之前的步骤,但缺少实际的比较算法。

2 个答案:

答案 0 :(得分:4)

有关的实现可以在here中找到。假设我们要检查两个sets vw是否相等,算法就可以这样进行:

  1. 检查它们的大小是否相等。如果不是,请返回false

这引用了size的{​​{1}}属性,因此它是恒定时间操作。

  1. 检查两个PySetObject是否均为sets。如果是这样,并且它们的哈希值不同,则返回frozensets

同样,这引用了false的{​​{1}}属性,这是一个恒定时间的操作。之所以可以这样做是因为hash是不可变的对象,因此在创建它们时会计算其哈希值。

  1. 检查PySetObject是否是frozensets的子集。

这是通过遍历w的每个元素并检查其是否存在于v中来完成的。

必须在所有v上执行迭代,因此迭代的大小最差是线性的(如果在最后一个位置发现了不同的元素)。

w的成员资格测试通常在平均情况下花费固定时间,而在最坏情况下花费线性时间;将两者结合起来,可以得到平均时间为v的线性时间,最坏情况下的时间与sets成比例。

从某种意义上讲,这是最坏情况的平均情况,因为它假定前两个检查总是返回v。如果您的数据仅很少具有相等大小的len(v) * len(w),它们也具有相同的哈希值但包含不同的对象,那么在一般情况下,比较仍将在恒定时间内进行。

答案 1 :(得分:3)

setfrozenset都使用the set_richcompare() function进行相等性测试。这里没有区别。

如其他答案所述,

true比较大小然后散列。然后,它checks whether one is a subset of the other仅循环遍历集合1中的每个元素,并检查它是否在集合2中。否则,该检查与checking whether an element is in a set相同。这是通过哈希表查找完成的,对具有相等哈希值的项目进行线性搜索。存在检查的复杂度为O(1) amortized or O(len(s)) worst-case,因此对sets的检查的复杂度为O(len(s1))摊销,或者O(len(s1)* len(s2))最差-情况。