在python中,set.pop()是否确定?

Nir*_*iel 18 python set

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

我想知道的是,当集合具有相同的历史记录时,pop是否总是会返回相同的元素.当然,在python的一个版本中,我不介意python的不同版本/实现是否有自己的功能.特别是,我问的是python 2.7.在这种情况下,这不仅仅是api的实现问题.

我在游戏的程序性地牢生成器中使用了很多集合,我希望结果对于给定的种子是确定性的.

ale*_*xis 28

答案一般是否定的.@Christophe和@Marcin(un)帮助指向的python源显示元素按它们在哈希表中出现的顺序弹出.因此,弹出顺序(可能是迭代顺序)确定性的,但仅适用于固定的散列值.根据文档中的注释,这是数字的情况,但不是字符串的情况,顺便提一下也直接涉及到你的问题:__hash__

请注意,默认情况下,str,bytes和datetime对象的hash()值使用不可预测的随机值"salted".虽然它们在单个Python进程中保持不变,但是在重复调用Python之间它们是不可预测的.

[...]

更改哈希值会影响dicts,集和其他映射的迭代顺序.Python从未对此排序做出保证(通常在32位和64位版本之间有所不同).

编辑:正如@Marcin指出的那样,我引用的链接不适用于Python 2.哈希随机化成为Python 3.3的默认设置.默认情况下,Python 2.7没有故意的非确定性字符串散列.

通常,对于其散列不是其值的可重复函数的任何对象(例如,如果散列基于存储器地址),这是一个问题.但相反,如果您__hash__为集合中的对象定义自己的方法,则可以预期它们将以可重现的顺序返回.(假设集合的历史和平台保持固定).


mik*_*iku 6

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

简而言之:不,set.pop()不是确定性的.不要假设任何订单,因为API明确说明了这一点

set对象是无序集合