python - 为什么由不同初始化的集合构成的元组是相等的?

标签 python set comparison tuples hashtable

我期望以下两个元组

>>> x = tuple(set([1, "a", "b", "c", "z", "f"]))
>>> y = tuple(set(["a", "b", "c", "z", "f", 1]))

比较不平等,但他们不:

>>> x == y
>>> True

这是为什么呢?

最佳答案

乍一看,似乎 x 应该总是等于 y,因为由相同元素构造的两个集合总是相等的:

>>> x = set([1, "a", "b", "c", "z", "f"])
>>> y = set(["a", "b", "c", "z", "f", 1])
>>> x
{1, 'z', 'a', 'b', 'c', 'f'}
>>> y
{1, 'z', 'a', 'b', 'c', 'f'}
>>> x == y
True

然而并非总是由两个相等的集合构成的元组(或其他有序集合)相等。

实际上,您比较的结果有时是True,有时是False,至少在Python >= 3.3 中是这样。测试以下代码:

# compare.py
x = tuple(set([1, "a", "b", "c", "z", "f"]))
y = tuple(set(["a", "b", "c", "z", "f", 1]))
print(x == y)

...一千次:

$ for x in {1..1000}
> do
>   python3.3 compare.py
> done | sort | uniq -c
147 False
853 True

这是因为,从 Python 3.3 开始,字符串、字节和日期时间的哈希值是随机的,因为 security fix .根据哈希值的不同,可能会发生“冲突”,这意味着订单项存储在底层数组中(因此迭代顺序)取决于插入顺序。

以下是文档中的相关内容:

Security improvements:

  • Hash randomization is switched on by default.

https://docs.python.org/3/whatsnew/3.3.html

EDIT:因为在评论中提到上面的 True/False 比率表面上令人惊讶......

集合,就像字典一样,被实现为哈希表 - 所以如果发生冲突,表中的项目顺序(以及迭代的顺序)将取决于首先添加的项目(在 中有所不同xy 在这种情况下)以及用于散列的种子(自 3.3 以来的 Python 调用不同)。由于在设计上碰撞很少见,并且此问题中的示例是较小的集合,因此该问题并不像人们最初想象的那样经常出现。

有关 Python 实现字典和集合的详细说明,请参阅 The Mighty Dictionary .

关于python - 为什么由不同初始化的集合构成的元组是相等的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26115765/

相关文章:

python - Openerp 中的序列格式

python - 识别django中数据库对象是什么类型

c++ - C++ 中的合并集合,以及重载运算符

Java:比较整数和字符串 - 性能

java - 比较不同格式的图像像素的简单方法(工具?)?

python - 如果程序在 Python 3 中失败则跳转到脚本末尾

python - python 程序如何检查自己的 md5sum?

python - max 在集合列表上做什么?

go - 不同类型集的集合操作的实现策略

algorithm - 比较算法