我期望以下两个元组
>>> 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.
EDIT:因为在评论中提到上面的 True
/False
比率表面上令人惊讶......
集合,就像字典一样,被实现为哈希表 - 所以如果发生冲突,表中的项目顺序(以及迭代的顺序)将取决于首先添加的项目(在 中有所不同x
和 y
在这种情况下)以及用于散列的种子(自 3.3 以来的 Python 调用不同)。由于在设计上碰撞很少见,并且此问题中的示例是较小的集合,因此该问题并不像人们最初想象的那样经常出现。
有关 Python 实现字典和集合的详细说明,请参阅 The Mighty Dictionary .
关于python - 为什么由不同初始化的集合构成的元组是相等的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26115765/