更新:Pythonの3.6、dict
はオーダーを保持new implementationを有しています。しかし、これは実装の詳細なので、依存するべきではありません。
これは、Python 3.3でenabled by default( "セキュリティの強化" にスクロールダウン)であった2012年からsecurity fix、の結果です。発表から
:
ハッシュのランダム化は、dictsの繰り返し順序を引き起こし、 予測不可能とPythonの実行を横切って異なることが設定されます。 Pythonは、dictまたはset内のキーの反復順序を 保証していないので、アプリケーションは決して に依存することをお勧めします。歴史的には、辞書の反復順序は、 のリリースで頻繁に変更されておらず、 Pythonの連続した実行の間は常に一貫していました。したがって、いくつかの既存のアプリケーションは、dictまたはset orderingに依存している可能性があります。 信頼できない入力を受け付けない多くのPythonアプリケーションがこの攻撃に対して脆弱ではないという事実があるため、安定したPythonリリース では、HASHのランダム化はデフォルトでは無効になっています。
上記のように、大文字の最後のビットは、Python 3.3ではもはや真ではありません。
も参照してください。object.__hash__()
documentation(「ノート」のサイドバー)。
絶対に必要な場合は、環境変数を0
に設定して、この動作の影響を受けるバージョンのPythonでハッシュランダム化を無効にすることができます。
あなたの反例:
list({str(i): i for i in range(10)}.keys())
...異なる順序の数がハッシュ衝突が処理されるdue to限定的ではあるが実際にはないは常に、Pythonの3.3で同じ結果が得られない:
$ for x in {0..999}
> do
> python3.3 -c "print(list({str(i): i for i in range(10)}.keys()))"
> done | sort | uniq -c
61 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
73 ['1', '0', '3', '2', '5', '4', '7', '6', '9', '8']
62 ['2', '3', '0', '1', '6', '7', '4', '5', '8', '9']
59 ['3', '2', '1', '0', '7', '6', '5', '4', '9', '8']
58 ['4', '5', '6', '7', '0', '1', '2', '3', '8', '9']
55 ['5', '4', '7', '6', '1', '0', '3', '2', '9', '8']
62 ['6', '7', '4', '5', '2', '3', '0', '1', '8', '9']
63 ['7', '6', '5', '4', '3', '2', '1', '0', '9', '8']
60 ['8', '9', '0', '1', '2', '3', '4', '5', '6', '7']
66 ['8', '9', '2', '3', '0', '1', '6', '7', '4', '5']
65 ['8', '9', '4', '5', '6', '7', '0', '1', '2', '3']
53 ['8', '9', '6', '7', '4', '5', '2', '3', '0', '1']
62 ['9', '8', '1', '0', '3', '2', '5', '4', '7', '6']
52 ['9', '8', '3', '2', '1', '0', '7', '6', '5', '4']
73 ['9', '8', '5', '4', '7', '6', '1', '0', '3', '2']
76 ['9', '8', '7', '6', '5', '4', '3', '2', '1', '0']
この回答の冒頭で述べたように、これはPython 3.6ではなくなりました。
$ for x in {0..999}
> do
> python3.6 -c "print(list({str(i): i for i in range(10)}.keys()))"
> done | sort | uniq -c
1000 ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
なぜ、これは '{str(i):i for i in range(10)} 'には当てはまりませんか? – Anaphory
このランダム化をどのように無効にするのですか? – nmz787
@ nmz787 https://docs.python.org/3/using/cmdline.html#envvar-PYTHONHASHSEED –