【问题标题】:Is iterating over the same frozenset guaranteed always to produce the items in the same order? (Python 3)是否保证迭代相同的frozenset 总是以相同的顺序生成项目? (Python 3)
【发布时间】:2019-03-17 01:28:54
【问题描述】:

例如,当我执行frozen = frozenset(('kay', 'snow queen')),然后执行tuple(frozen),我得到('kay', 'snow queen')。 (何时/如何)iter(frozen) 是否有可能以不同的顺序生产物品? (何时/如何)tuple(frozen) 将返回('snow queen', 'kay')

我几乎一直在使用 Python 3,但我也会对 Python 2 感到好奇。

【问题讨论】:

    标签: python iterator set persistent-storage reliability


    【解决方案1】:

    默认情况下,str 对象的哈希值使用不可预知的随机值加盐。尽管它们在单个 Python 进程中保持不变,但在 Python 的重复调用之间它们是不可预测的。更改哈希值会影响集合的迭代顺序。

    所以,当哈希随机化开启时,你会以不同的顺序获得项目:

    $ for i in {1..10}; do python3 -c "frozen = frozenset(('kay', 'snow queen')); print(list(frozen))"; done
    ['snow queen', 'kay']
    ['snow queen', 'kay']
    ['snow queen', 'kay']
    ['snow queen', 'kay']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['snow queen', 'kay']
    ['kay', 'snow queen']
    ['snow queen', 'kay']
    ['snow queen', 'kay']
    

    如果你disable it,你会得到一个可重复但任意的顺序:

    $ export PYTHONHASHSEED=0
    $ for i in {1..10}; do python3 -c "frozen = frozenset(('kay', 'snow queen')); print(list(frozen))"; done
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    ['kay', 'snow queen']
    

    从 Python 3.3 开始,哈希随机化默认启用为 workaround a security vulnerability

    另请参阅:the -R switch to the interpreter

    【讨论】:

    • 如果我的意图是,在同一个 Python 进程中,我总是得到相同的结果(继续示例)tuple(frozen),那么我可以简单地做@ 987654331@、iter(frozen) 等,只要我想要以相同顺序排列的项目 --- 无论随机化设置如何。这是正确的吗?
    • 是的,但是您依赖于实现细节。我建议使用orderedset
    • 感谢您的建议。不过,我相信orderedset 对于我目前的应用程序来说是不必要的,即创建一次 (frozen)set,然后以任何顺序使用这些项目(但在整个 Python 过程中始终以相同的顺序)。我认为foo = tuple(frozenset(('kay', 'snow queen'))),此后foo,将完成这项工作。或者,bar = tuple(set(('kay', 'snow queen'))),此后bar。不过,为您提供信息丰富且有用的答案(包括 cmets)+1。
    猜你喜欢
    • 2021-10-21
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2010-09-12
    • 1970-01-01
    相关资源
    最近更新 更多