Python | データ構造強化:collections.OrderedDict

Python Python
スポンサーリンク

概要(OrderedDict は「挿入順や並べ替えを意図的に扱える辞書」)

collections.OrderedDict は「辞書の順序」を明確に扱うための拡張辞書です。Python 3.7以降、通常の dict も挿入順を保持しますが、OrderedDict には順序操作に特化したメソッド(move_to_end、popitem など)や、順序を含めて等価性を判定する特徴があり、順序がロジックの意味を持つ場面で有用です。

基本の使い方(ここが重要)

作成とアクセス(挿入順を保持して反復できる)

from collections import OrderedDict

od = OrderedDict()
od["name"] = "hanako"
od["age"] = 30
od["city"] = "Tokyo"

print(list(od.keys()))    # ['name', 'age', 'city'](挿入順)
print(od["age"])          # 30(辞書と同様アクセス)
for k, v in od.items():
    print(k, v)           # 反復も挿入順で出る
Python

既存データからの初期化(タプル列やソート結果を保持)

from collections import OrderedDict

pairs = [("b", 2), ("a", 1), ("c", 3)]
od = OrderedDict(pairs)              # pairs の順番を保持
od_sorted = OrderedDict(sorted(pairs))  # ソートした順を保持
print(list(od_sorted.items()))       # [('a',1),('b',2),('c',3)]
Python

重要ポイントの深掘り(dict との違いと順序操作)

「順序の意味」をコード化できる(比較と用途の違い)

  • 通常の dict は順序を保持しますが、等価比較では順序は無視されます。
  • OrderedDict は「キー・値・挿入順」が一致して初めて等しいと判定されます。順序が仕様の一部なら OrderedDict で表現するのが安全です。
from collections import OrderedDict

od1 = OrderedDict([("a", 1), ("b", 2)])
od2 = OrderedDict([("b", 2), ("a", 1)])
print(od1 == od2)  # False(順序が違う)

d1 = {"a": 1, "b": 2}
d2 = {"b": 2, "a": 1}
print(d1 == d2)    # True(順序は比較に影響しない)
Python

move_to_end と popitem で「順序を操作」できる

  • move_to_end(key, last=True): 指定キーを末尾(last=True)または先頭(last=False)へ移動。
  • popitem(last=True): 末尾(LIFO)または先頭(FIFO)から要素を取り出す。
from collections import OrderedDict

od = OrderedDict([("A", 1), ("B", 2), ("C", 3)])
od.move_to_end("A")                 # 'A' を末尾へ → A が最後に
print(list(od))                     # ['B','C','A']
k, v = od.popitem(last=False)       # 先頭から取り出し(FIFO)→ ('B',2)
print(k, v, list(od))               # B 2 ['C','A']
Python

「並べ替えた結果」を安定に保持できる(ソート・重み順)

出力順や表示順を保証したいとき、並べ替えたペア列から OrderedDict を作れば、その順序をその後の操作まで保持できます。

from collections import OrderedDict

scores = {"alice": 70, "bob": 85, "hanako": 92}
od = OrderedDict(sorted(scores.items(), key=lambda kv: kv[1], reverse=True))
print(list(od.items()))  # [('hanako', 92), ('bob', 85), ('alice', 70)]
Python

実務での使いどころ(順序が仕様になる場面)

出力の順序保証(レポート・JSON・設定ファイルの安定化)

差分比較やレビューで「毎回同じ順序」が重要なら、OrderedDict にしてから出力すると安定します。

import json
from collections import OrderedDict

cfg = OrderedDict([("version", 1), ("name", "app"), ("features", ["A","B"])])
print(json.dumps(cfg, ensure_ascii=False, indent=2))  # キー順をそのまま出力
Python

最近使われた順の管理(LRU 風の並べ替え)

キャッシュや履歴で「最後に使ったものを末尾へ寄せる」動きが自然に書けます。

from collections import OrderedDict

class LRU:
    def __init__(self, cap: int):
        self.cap = cap
        self.od = OrderedDict()
    def get(self, key):
        if key in self.od:
            self.od.move_to_end(key)   # 最近使ったので末尾へ
            return self.od[key]
        return None
    def put(self, key, value):
        self.od[key] = value
        self.od.move_to_end(key)
        if len(self.od) > self.cap:
            self.od.popitem(last=False)  # 古いもの(先頭)を捨てる
Python

ヘッダ順の維持・ユーザー定義順の尊重

CSVやフォームの「見せる順」「入力順」をそのまま持ち回ると、意図通りの表示や検証が可能になります。

例題で身につける(定番から一歩先まで)

例題1:ソート済みの順位表を出力

from collections import OrderedDict

scores = {"coffee": 92, "tea": 81, "sugar": 75}
ranked = OrderedDict(sorted(scores.items(), key=lambda kv: kv[1], reverse=True))
for name, score in ranked.items():
    print(f"{name:<6} {score:>3}")
Python

例題2:FIFO/LIFO で取り出し方を切り替える

from collections import OrderedDict

od = OrderedDict([("task1", "A"), ("task2", "B"), ("task3", "C")])
print(od.popitem(last=False))  # 先頭(FIFO)→ ('task1','A')
print(od.popitem(last=True))   # 末尾(LIFO) → ('task3','C')
Python

例題3:アクセス順に並べ替える(履歴)

from collections import OrderedDict

hist = OrderedDict()
for k in ["A","B","C","A","B"]:
    hist[k] = hist.get(k, 0) + 1
    hist.move_to_end(k)   # アクセスしたものを末尾へ
print(list(hist.items())) # [('C',1),('A',2),('B',2)](直近が後ろ)
Python

例題4:ユーザー指定のキー順を保持した設定出力

from collections import OrderedDict
import json

order = ["title", "author", "date", "tags"]
data = {"author":"hanako","tags":["py"],"title":"note","date":"2025-12-15"}

od = OrderedDict((k, data[k]) for k in order)
print(json.dumps(od, ensure_ascii=False, indent=2))
Python

まとめ

OrderedDict は「順序が意味を持つ」場面で力を発揮します。通常の dict も挿入順を保持しますが、OrderedDict は順序を含めて等価性を判定し、move_to_end・popitem など順序操作のための専用メソッドを備えています。並べ替えた結果を安定保持、FIFO/LIFO の取り出し、最近使用の並べ替え、出力順の保証など、順序が仕様の一部なら迷わず採用しましょう。

タイトルとURLをコピーしました