为什么从不同初始化集合构建的元组相等? [英] Why are tuples constructed from differently initialized sets equal?

查看:137
本文介绍了为什么从不同初始化集合构建的元组相等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我预期以下两个元组

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

比较不等号,但它们不会:

to compare unequal, but they don't:

>>> x == y
>>> True

为什么?

推荐答案

乍一看, x 应始终等于 y 由相同元素构建的集合总是相等的:

At first glance, it appears that x should always equal y, because two sets constructed from the same elements are always equal:

>>> 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

em> 总是这样的情况下,从两个等集构造的元组(或其他有序集合)是相等的。

However, it is not always the case that tuples (or other ordered collections) constructed from two equal sets are equal.

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

In fact, the result of your comparison is sometimes True and sometimes False, at least in Python >= 3.3. Testing the following code:

# 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

这是因为3.3,字符串,字节和数据时间的哈希值会随着安全修复。根据哈希是什么,可能会发生冲突,这意味着订单项存储在底层数组中(因此,迭代顺序)取决于插入顺序。

This is because, since Python 3.3, the hash values of strings, bytes and datetimes are randomized as a result of a security fix. Depending on what the hashes are, "collisions" may occur, which will mean that the order items are stored in the underlying array (and therefore the iteration order) depends on the insertion order.

这是文档中的相关位:


安全性改进:

Security improvements:


  • 默认情况下已启用散列随机化。

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

EDIT :由于评论中提到 True / False 上面的比率是表面上令人惊讶的...

EDIT: Since it's mentioned in the comments that the True/False ratio above is superficially surprising ...

像字典一样,集合被实现为哈希表 - ,表中项目的顺序(以及迭代的顺序)将取决于首先添加的项目(在 x y中不同) )和用于哈希的种子(从3.3开始,不同的Python调用)。由于碰撞是设计罕见的,并且这个问题中的例子是很少的集合,所以这个问题不会像以前一样经常出现。

Sets, like dictionaries, are implemented as hash tables - so if there's a collision, the order of items in the table (and so the order of iteration) will depend both on which item was added first (different in x and y in this case) and the seed used for hashing (different across Python invocations since 3.3). Since collisions are rare by design, and the examples in this question are smallish sets, the issue doesn't arise as often as one might initially suppose.

有关彻底的解释的Python实现字典和集合,请参见强大字典

For a thorough explanation of Python's implementation of dictionaries and sets, see The Mighty Dictionary.

这篇关于为什么从不同初始化集合构建的元组相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆