【问题标题】:How is frozenset equality implemented in Python?如何在 Python 中实现frozenset 相等?
【发布时间】:2019-06-10 03:36:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: python cpython frozenset


    【解决方案1】:

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

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

    这引用了PySetObjectsize属性,所以它是一个常数时间的操作。

    1. 检查sets 是否都是frozensets。如果是这样,并且它们的哈希值不同,则返回 false

    同样,这引用了PySetObjecthash 属性,这是一个常数时间操作。这是可能的,因为frozensets 是不可变对象,因此在创建它们时会计算它们的哈希值。

    1. 检查w 是否是v 的子集。

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

    迭代必须在整个v 上执行,因此在最坏的情况下它的大小是线性的(如果在最后一个位置找到不同的元素)。

    sets 的成员资格测试通常在平均情况下需要恒定时间,在最坏情况下需要线性时间;将两者结合起来,在平均情况下,时间与 v 的大小呈线性关系,在最坏情况下,时间与 len(v) * len(w) 成正比。

    从某种意义上说,这是最坏情况的平均情况,因为它假定前两次检查总是返回true。如果您的数据很少倾向于具有相同大小的sets,它们也具有相同的哈希值但包含不同的对象,那么在平均情况下,比较仍将在恒定时间内运行。

    【讨论】:

    • 哈希并不能说明这两个对象是相同的。他们告诉他们是否不同。如果哈希匹配,则进行比较。
    • @DanD。你是对的;我误读了代码。我会编辑我的答案。谢谢!
    【解决方案2】:

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

    set_richcompare(),正如其他答案所提到的,比较大小然后散列。然后,它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,因此set_issubset() 的检查复杂度为 O(len(s1)) 摊销,或 O(len(s1)*len(s2)) 最坏情况。

    【讨论】:

      猜你喜欢
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多