首页 > 解决方案 > list(frozenset()) 返回的元素顺序是如何确定的?

问题描述

我在 Python 中有以下示例性设置:

a = list(frozenset(['haha', 'lol']))
b = list(frozenset(['lol', 'haha']))

a == b

总是返回True

相同元素的frozenset列表是否有可能通过上述设置返回False ?

标签: pythonlistsetfrozenset

解决方案


(冻结)集之间的等价语义是,如果它们包含等价项,则它们是等价的。集合没有顺序。

但是,由于列表具有顺序,因此转换为列表可能会导致它们不等价(取决于(冻结)集的迭代顺序 - 这是一个实现细节)。

下面是一个内部实现中的冲突示例,该冲突由于插入顺序而导致不同的迭代顺序(这是在 CPython 实现中):

>>> a = list(frozenset([1, 9]))
>>> b = list(frozenset([9, 1]))
>>> a == b
False

字符串示例:

首先我们需要找到一个碰撞(我不再赘述):

>>> hash('1') % 8
0
>>> hash('2') % 8
5
>>> hash('3') % 8
2
>>> hash('4') % 8
3
>>> hash('5') % 8
1
>>> hash('6') % 8
4
>>> hash('7') % 8 
5  # same as '2' ! Found!

现在我们需要以不同的顺序添加到集合中以导致重新散列(同样,不详述):

>>> s1, s2 = '2', '7'
>>> a = list(frozenset([s1, s2]))
>>> b = list(frozenset([s2, s1]))
>>> a == b
False

推荐阅读