Python 中 frozenset 相等性是如何实现的?
How is frozenset equality implemented in Python?
CPython 中 frozenset 相等性是如何实现的?特别是,我想知道 fronzenset 中的各个元素如何相互比较以及它们的总时间复杂度。
我看了set and frozenset difference in implementation and 。
第二个 link 中的答案涵盖了比较集合中各个元素之前的步骤,但缺少实际的比较算法。
可以找到有问题的实现 here。算法是这样的,假设我们要检查两个 sets
v
和 w
是否相等:
- 检查它们的大小是否相等。如果不是,return
false
。
这引用了 PySetObject
的 size
属性,因此它是一个常量时间操作。
- 检查
sets
是否都是 frozensets
。如果是这样,并且它们的哈希值不同,return false
.
同样,这引用了 PySetObject
的 hash
属性,这是一个常量时间操作。这是可能的,因为 frozensets
是不可变对象,因此在创建它们时会计算它们的哈希值。
- 检查
w
是否是 v
的子集。
这是通过遍历 v
的每个元素并检查它是否存在于 w
中来完成的。
迭代必须在整个 v
上执行,因此在最坏的情况下它的大小是线性的(如果在最后一个位置找到不同的元素)。
sets
的成员资格测试通常在平均情况下需要常数时间,在最坏情况下需要线性时间;将两者结合起来,在平均情况下,时间与 v
的大小成线性关系,在最坏的情况下,时间与 len(v) * len(w)
成正比。
从某种意义上说,这是最坏情况的平均情况,因为它假设前两次检查总是 return true
。如果您的数据很少倾向于 equal-size sets
也具有相同的哈希值但包含不同的对象,那么在平均情况下,比较仍将 运行 在常数时间内。
两者都 set and frozenset use the set_richcompare()
function 用于相等性测试。这里没有区别。
set_richcompare()
,正如其他答案所提到的,比较大小然后散列。然后,它 checks whether one is a subset of the other, which just loops over every element in set 1, and checks if it is in set 2. This check is otherwise identical to checking whether an element is in a set. This is done by hash-table lookup, with a linear search over items with equal hashes. The complexity for the existence check is O(1) amortized or O(len(s)) worst-case,因此 set_issubset()
的检查具有 O(len(s1)) 摊销的复杂性,或 O(len(s1)*len(s2)) worst-case。
CPython 中 frozenset 相等性是如何实现的?特别是,我想知道 fronzenset 中的各个元素如何相互比较以及它们的总时间复杂度。
我看了set and frozenset difference in implementation and
第二个 link 中的答案涵盖了比较集合中各个元素之前的步骤,但缺少实际的比较算法。
可以找到有问题的实现 here。算法是这样的,假设我们要检查两个 sets
v
和 w
是否相等:
- 检查它们的大小是否相等。如果不是,return
false
。
这引用了 PySetObject
的 size
属性,因此它是一个常量时间操作。
- 检查
sets
是否都是frozensets
。如果是这样,并且它们的哈希值不同,returnfalse
.
同样,这引用了 PySetObject
的 hash
属性,这是一个常量时间操作。这是可能的,因为 frozensets
是不可变对象,因此在创建它们时会计算它们的哈希值。
- 检查
w
是否是v
的子集。
这是通过遍历 v
的每个元素并检查它是否存在于 w
中来完成的。
迭代必须在整个 v
上执行,因此在最坏的情况下它的大小是线性的(如果在最后一个位置找到不同的元素)。
sets
的成员资格测试通常在平均情况下需要常数时间,在最坏情况下需要线性时间;将两者结合起来,在平均情况下,时间与 v
的大小成线性关系,在最坏的情况下,时间与 len(v) * len(w)
成正比。
从某种意义上说,这是最坏情况的平均情况,因为它假设前两次检查总是 return true
。如果您的数据很少倾向于 equal-size sets
也具有相同的哈希值但包含不同的对象,那么在平均情况下,比较仍将 运行 在常数时间内。
两者都 set and frozenset use the set_richcompare()
function 用于相等性测试。这里没有区别。
set_richcompare()
,正如其他答案所提到的,比较大小然后散列。然后,它 checks whether one is a subset of the other, which just loops over every element in set 1, and checks if it is in set 2. This check is otherwise identical to checking whether an element is in a set. This is done by hash-table lookup, with a linear search over items with equal hashes. The complexity for the existence check is O(1) amortized or O(len(s)) worst-case,因此 set_issubset()
的检查具有 O(len(s1)) 摊销的复杂性,或 O(len(s1)*len(s2)) worst-case。