[解決済み】Python 3.6+で辞書は順番に並びますか?
質問
Python 3.6 (少なくとも CPython の実装では) では、以前のバージョンと異なり、辞書が順序付けされます。これは実質的な変更のように見えますが、Python 3.6では ドキュメント . これは言語機能ではなく、CPythonの実装の詳細として説明されていますが、将来的にこれが標準になる可能性があることも示唆しています。
新しい辞書の実装は、要素の順序を維持しながら、古いものよりもどのように優れたパフォーマンスを発揮するのでしょうか?
以下は、ドキュメントに掲載されている文章です。
dict()
は、「コンパクト」な表現になりました。 PyPyによって開拓された . 新しい dict() のメモリ使用量は、Python 3.5 と比較して 20% から 25% 少なくなっています。 PEP 468 (Preserving order of **kwargs in a function.) が実装されています。この新しい実装の順序保持の側面は、実装の詳細とみなされ、依存すべきではありません (これは将来変わるかもしれませんが、現在と将来のすべての Python 実装で順序保持のセマンティクスを義務付けるために言語仕様を変更する前に、いくつかのリリースでこの新しい dict の実装を言語内に持つことが望まれます。これはまた、ランダム反復順序がまだ有効な古いバージョンの言語との下位互換性保持にも役立ちます、例えば Python 3.5).(Contributed by INADA Naoki in 課題27350 . アイデア 原案:Raymond Hettinger .)
2017年12月更新
dict
の保持挿入順序は
保証
Python 3.7 の場合
解決方法は?
<ブロッククオートPython 3.6+では、辞書は順序付けされますか?
それは
挿入順
[1]
. Python 3.6以降、PythonのCPython実装では、ディクショナリ
挿入されたアイテムの順番を記憶する
.
これはPython 3.6での実装の詳細とされている
を使用する必要があります。
OrderedDict
挿入順序が必要な場合、その順序は
保証
Pythonの他の実装にまたがって(他の順序付き動作の
[1]
).
Python 3.7時点 これはもはや実装の詳細ではなく、言語的な特徴となります。 GvRによるpython-devメッセージより :
<ブロッククオートDict keeps insertion order"で決まりです。ありがとうございます。
これは、単純に 頼りになる . Pythonの他の実装も、Python 3.7に準拠した実装でありたいなら、挿入順辞書を提供しなければなりません。
<ブロッククオート
Pythonはどのように
3.6
辞書の実装の方が
[2]
要素の順序を維持したまま、古いものよりも?
基本的に、以下の方法で 2つの配列を保持する .
-
最初の配列です。
dk_entries
は、エントリ ( タイプのPyDictKeyEntry
) を、挿入された順番に辞書に追加します。この配列は、新しい項目が常に最後に挿入される (挿入順) 追加専用の配列であるため、順序を維持することができます。 -
2つ目は
dk_indices
のインデックスを保持する。dk_entries
配列の対応するエントリの位置を示す値です。dk_entries
). この配列がハッシュテーブルとして機能します。キーがハッシュ化されるとき、それはdk_indices
をインデックス化し、対応するエントリを取得します。dk_entries
. インデックスのみが保持されるため、この配列のタイプは辞書の全体サイズに依存します(タイプはint8_t
(1
バイト)からint32_t
/int64_t
(4
/8
バイトで32
/64
ビットビルド)
これまでの実装では、型の疎な配列である
PyDictKeyEntry
とサイズ
dk_size
を超える配列は作成できないため、残念ながら多くの空き領域が発生します。
2/3 * dk_size
フル
パフォーマンス上の理由から
. (そして空いたスペースは
今も
があった。
PyDictKeyEntry
のサイズ!)。
のみであるため、現在はこの限りではありません。
必須
の疎な配列が格納されます。
intX_t
(
X
ディクショナリーのサイズに依存)
2/3 * dk_size
が満杯になることはありません。空いたスペースは、型から変更
PyDictKeyEntry
から
intX_t
.
したがって、明らかに、型
PyDictKeyEntry
を格納するための疎な配列よりも、はるかに多くのメモリを必要とします。
int
s.
会話の全文を見ることができます Python-Devで この機能に興味がある方は、ぜひ読んでみてください。
レイモンド・ヘッティンガー氏による原案では このアイデアの要点を捉えた、使用するデータ構造のビジュアライゼーションを見ることができます。
<ブロッククオート例えば、辞書。
d = {'timmy': 'red', 'barry': 'green', 'guido': 'blue'}
は現在、[keyhash, key, value]として格納されています。
entries = [['--', '--', '--'],
[-8522787127447073495, 'barry', 'green'],
['--', '--', '--'],
['--', '--', '--'],
['--', '--', '--'],
[-9092791511155847987, 'timmy', 'red'],
['--', '--', '--'],
[-6480567542315338377, 'guido', 'blue']]
その代わり、データは以下のように整理しておく。
indices = [None, 1, None, None, None, 0, None, 2]
entries = [[-9092791511155847987, 'timmy', 'red'],
[-8522787127447073495, 'barry', 'green'],
[-6480567542315338377, 'guido', 'blue']]
今、視覚的にお分かりのように、オリジナルの提案では、衝突を減らし、検索を高速化するために、多くのスペースが基本的に空になっています。新しいアプローチでは、スパースネスを本当に必要な場所、つまりインデックスに移動することで、必要なメモリを削減します。
<サブ [1]: というのも、OrderedDict が存在すると、 "ordered" は、 `dict` オブジェクトが *doesn't provide* している、さらなる動作を示唆しているからです。OrderedDicts は可逆的であり、順序を考慮したメソッドを提供し、主に順序を考慮した等値性テスト (`==`, `!=`) を提供します。現在、 `dict` はこれらの動作やメソッドを提供していません。
<サブ [2]: 新しい辞書の実装は、よりコンパクトに設計されているため、**メモリ面でより良いパフォーマンスを発揮します。スピードの面では、それほど劇的な違いはありませんが、新しいディクショナリーが若干のリグレッションを引き起こすかもしれない場所があります ( キーのルックアップなど ) 一方、他のもの (反復処理やリサイズが思い浮かびます) では、パフォーマンスが向上するはずです。 <サブ 全体として、特に実生活の場面では、導入されたコンパクトさにより、辞書の性能が向上する。
関連
-
[解決済み】ImportError: bs4という名前のモジュールがない(BeautifulSoup)
-
[解決済み】django インポートエラー - core.managementという名前のモジュールがない
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] Python 3で「1000000000000000 in range(1000000000000001)」はなぜ速いのですか?
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] 辞書のリストを辞書の値でソートするにはどうしたらいいですか?
-
[解決済み] Pythonで静的なクラス変数は可能ですか?
-
[解決済み】forループを使った辞書の反復処理
-
[解決済み】Pythonに三項条件演算子はありますか?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PicgoのイメージベッドツールをPythonで実装する
-
Python jiabaライブラリの使用方法について説明
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonの学習とデータマイニングのために知っておくべきターミナルコマンドのトップ10
-
Evidentlyを用いたPythonデータマイニングによる機械学習モデルダッシュボードの作成
-
[解決済み】numpy: true_divide で無効な値に遭遇
-
[解決済み】ImportError: PILという名前のモジュールがない
-
[解決済み】Flask ImportError: Flask という名前のモジュールがない
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】Flaskのテンプレートが見つからない【重複あり