在python中,set.pop()是确定性的吗?

2024-04-29 18:36:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道python集的元素没有排序。调用pop方法返回一个任意元素;我不介意。

我想知道的是,当集合具有相同的历史记录时,pop是否总是返回相同的元素。当然,在python的一个版本中,我不介意python的不同版本/实现是否做自己的事情。特别是,我要问的是Python2.7。在这种情况下,实现比api更重要。

我在一个程序化的地下城生成器中经常使用集合来进行游戏,我希望对于给定的种子,结果是确定的。


Tags: 方法版本api游戏元素历史记录排序情况
3条回答

The documentation没有指定它必须是确定性的,因此您应该假设它不是

一般来说,答案是否。python源代码,@Christophe和@Marcin(un)很有帮助地指出,元素是按照它们在哈希表中的出现顺序弹出的。因此,pop-order(以及可能的迭代顺序)是确定的,但仅适用于固定的散列值。 根据^{}文档中的注释,这是数字的情况,但字符串的不是,顺便说一下,这也直接涉及到您的问题:

Note by default the hash() values of str, bytes and datetime objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python.

[ ... ]

Changing hash values affects the iteration order of dicts, sets and other mappings. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).

编辑:正如@Marcin指出的,我引用的链接不适用于Python 2。 默认情况下,哈希随机化became the default with Python 3.3.Python 2.7没有有意的非确定性字符串哈希。

一般来说,对于散列不是其值的可重复函数的任何对象(例如,如果散列基于内存地址),这是一个问题。但是相反,如果为集合中的对象定义自己的__hash__方法,则可以预期它们将以可复制的顺序返回。(前提是设备的历史和平台保持固定)。

在内部,我认为情况类似于dict。顺序由hash算法决定,在的一些情况下,将产生相同的结果。但不应该依赖于此,因为一旦元素的数量变大,集合将遇到冲突(即内部散列),最终导致不同的顺序。

简而言之:不,set.pop()不是确定性的。不要假设任何顺序,因为API明确声明

a set object is an unordered collection

相关问题 更多 >