閉じる

Pythonの辞書をキー/値でソートする方法(sortedとkey引数)

辞書の中身を「キー順」や「値の大小」で並べ替えたい場面は多いですが、辞書そのものにはソート機能がありません。

Pythonではsorted関数とkey引数を使って、辞書のキー、値、項目(キーと値のペア)を柔軟に並べ替えます。

本記事では基本から実用までを丁寧に解説します。

辞書ソートの基本

Pythonの辞書と順序保持の前提

Python 3.7以降の標準のdictは、挿入順序を保持します。

つまり、ある順序でキーと値のペア(項目)を追加すると、その順序で反復(走査)されます。

ただし「辞書自体を直接ソートする」ことはできません。

ソートはあくまで「並べ替えられた新しいリストを作る」操作であり、その結果を必要に応じて新しい辞書として構築し直します。

次の短い例で、挿入順序が保持されることを確認できます。

Python
# 挿入順序が保持される例
d = {}
d["b"] = 2
d["a"] = 1
d["c"] = 3

for k, v in d.items():
    print(k, v)
実行結果
b 2
a 1
c 3

ソートはsortedで行う key引数とreverseの役割

並べ替えは組み込み関数sorted(iterable, *, key=None, reverse=False)で行います。

sortedはイテラブル(反復可能オブジェクト)を受け取り、新しいリストを返します。

  • key: 各要素から比較用の値を取り出す関数を指定します。
  • reverse: 降順にしたい場合はTrueを指定します(デフォルトは昇順)。

辞書を扱う場合、sortedに渡す対象は次のいずれかです。

  • d.keys()(または単にd) … キーの並べ替え
  • d.values() … 値の並べ替え
  • d.items() … (キー, 値)タプルの並べ替え

key関数の中で、どの要素を基準に並べるかを柔軟に指定できます。

keys values items どれをソートするか

用途に応じて、何をsortedに渡すかを選びます。

基準にしたい情報がkeyだけか、valueだけか、両方かで使い分けます。

対象返る型key関数に渡る値典型用途
d または d.keys()キーのリスト各キーキー名でのソート、キーを基準に2次基準を作る
d.values()値のリスト各値単に値の大小を並べたい(どのキーかは不要)
d.items()(キー, 値)のリスト各(キー, 値)タプルキーや値を自由に基準化し、並べたペアをそのまま再構築したい

以降の実例は、基本的にd.items()sortedし、必要なら新しい辞書へ組み直す流れを示します。

キーでソートする方法

キーで昇順ソート sortedとdict.items

キーを辞書順(昇順)にしたい場合、d.items()をそのままsortedに渡せば、(キー, 値)タプルはまずキーで比較されるため簡単です。

Python
# キーで昇順ソート
d = {"banana": 3, "Apple": 5, "cherry": 1}

# (キー, 値)のリストとしてソート
pairs = sorted(d.items())  # デフォルトはキー昇順

print(pairs)  # 並びを確認
# 新しい辞書を並び替え順で構築
sorted_dict = dict(pairs)

print(sorted_dict)
実行結果
[('Apple', 5), ('banana', 3), ('cherry', 1)]
{'Apple': 5, 'banana': 3, 'cherry': 1}

キーで降順ソート reverse=True

降順にしたいときはreverse=Trueを指定します。

Python
# キーで降順ソート
d = {"banana": 3, "Apple": 5, "cherry": 1}
sorted_dict_desc = dict(sorted(d.items(), reverse=True))
print(sorted_dict_desc)
実行結果
{'cherry': 1, 'banana': 3, 'Apple': 5}

大文字小文字を無視したキーソート str.lowerをkeyに

キーの大小を無視してソートしたい場合は、キーを小文字化した値を比較基準にします。

str.lowerまたはより包括的なstr.casefoldが使えます。

Python
# 大文字小文字を無視してキーをソート
d = {"banana": 3, "Apple": 5, "cherry": 1, "apricot": 2}

# key関数で(キー, 値)タプルの0番目(キー)を小文字化して比較
pairs_ci = sorted(d.items(), key=lambda kv: kv[0].lower())
print(dict(pairs_ci))

# 国際化を考慮するなら casefold の方が厳密
pairs_ci2 = sorted(d.items(), key=lambda kv: kv[0].casefold())
print(dict(pairs_ci2))
実行結果
{'Apple': 5, 'apricot': 2, 'banana': 3, 'cherry': 1}
{'Apple': 5, 'apricot': 2, 'banana': 3, 'cherry': 1}

値でソートする方法

値で昇順ソート key=lambda item[1]

値を基準にしたい場合は、(キー, 値)タプルの1番目の要素(値)をkey関数で返すようにします。

Python
# 値で昇順ソート
d = {"apple": 5, "banana": 3, "cherry": 1}

pairs_by_value = sorted(d.items(), key=lambda kv: kv[1])
print(pairs_by_value)
print(dict(pairs_by_value))
実行結果
[('cherry', 1), ('banana', 3), ('apple', 5)]
{'cherry': 1, 'banana': 3, 'apple': 5}

補足として、キーを値で並べたいだけならsorted(d, key=d.get)というイディオムも便利です。

Python
# キーを値の小さい順に並べる(結果はキーのリスト)
d = {"apple": 5, "banana": 3, "cherry": 1}
keys_by_value = sorted(d, key=d.get)
print(keys_by_value)
実行結果
['cherry', 'banana', 'apple']

値で降順ソート reverse=True

降順はreverse=Trueを指定するだけです。

Python
# 値で降順ソート
d = {"apple": 5, "banana": 3, "cherry": 1}
sorted_desc = dict(sorted(d.items(), key=lambda kv: kv[1], reverse=True))
print(sorted_desc)
実行結果
{'apple': 5, 'banana': 3, 'cherry': 1}

数値の絶対値でソート key=absやitemgetter

値が負数を含む場合、絶対値で並べたいケースがあります。

その場合はabskey関数に組み込みます。

operator.itemgetterを使うと「タプルの何番目を基準にするか」を明示的に書けます。

Python
from operator import itemgetter

# 絶対値でソートする例
d = {"pos_small": 2, "neg_large": -10, "pos_large": 8, "neg_small": -3}

# その1: ラムダで値の絶対値を返す
pairs_abs = sorted(d.items(), key=lambda kv: abs(kv[1]))
print(pairs_abs)
print(dict(pairs_abs))

# その2: itemgetterで値を取り出してからabsを適用
get_value = itemgetter(1)
pairs_abs2 = sorted(d.items(), key=lambda kv: abs(get_value(kv)))
print(dict(pairs_abs2))
実行結果
[('pos_small', 2), ('neg_small', -3), ('pos_large', 8), ('neg_large', -10)]
{'pos_small': 2, 'neg_small': -3, 'pos_large': 8, 'neg_large': -10}
{'pos_small': 2, 'neg_small': -3, 'pos_large': 8, 'neg_large': -10}

並べ替え結果の扱いと注意点

並び替えた順で新しい辞書を作る dict内包表記

並び替えた結果から「その順序で走査できる新しい辞書」を作るには、dict(...)コンストラクタか辞書内包表記を使います。

Python 3.7以降はdictが挿入順を保持するので、並び替え順で挿入すればその順序が保たれます。

Python
# dictコンストラクタで再構築
d = {"b": 2, "a": 1, "c": 3}
sorted_items = sorted(d.items())  # キー昇順
sorted_dict = dict(sorted_items)
print(sorted_dict)

# 辞書内包表記でも同様
sorted_dict2 = {k: v for k, v in sorted(d.items(), key=lambda kv: kv[1])}  # 値昇順
print(sorted_dict2)
実行結果
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'c': 3, 'b': 2}

注: もともと辞書のキーは一意なので、items()を経由して再構築するときに上書きが発生する心配は通常ありません。

複数条件で安定ソートする タプルkeyとitemgetter

Pythonのsortedは安定ソートです。

複数の基準で並べたい場合、次の2通りが実用的です。

  • 単一回のsortedで「タプルの比較キー」を返す
  • 複数回のsortedを「劣後→優先」の順に適用する(安定性を利用)
Python
from operator import itemgetter

d = {
    "alice": 3,
    "bob": 10,
    "anna": 10,
    "carol": 2,
}

# 方法1: タプルの比較キー
# 基準: 値(降順) → キー(昇順)
pairs_multi = sorted(
    d.items(),
    key=lambda kv: (-kv[1], kv[0])  # 1番目に値の降順、2番目にキーの昇順
)
print(pairs_multi)

# 方法2: 安定ソートの二段適用
# まず劣後基準(キー昇順)でソートし、その結果に優先基準(値降順)を掛ける
pairs_step1 = sorted(d.items(), key=itemgetter(0))            # キー昇順
pairs_step2 = sorted(pairs_step1, key=itemgetter(1), reverse=True)  # 値降順
print(pairs_step2)
実行結果
[('anna', 10), ('bob', 10), ('alice', 3), ('carol', 2)]
[('anna', 10), ('bob', 10), ('alice', 3), ('carol', 2)]

sortedとlist.sortの違い 辞書を直接はソートできない

sorted(iterable, ...)は新しいリストを返す関数で、あらゆるイテラブルに使えます。

辞書そのものはイテラブルですが、反復するとキーが得られるため、sorted(d)は「キーを並べたリスト」を返します。

それに対して、list.sort(...)はリストに対する破壊的(インプレース)メソッドで、戻り値はNoneです。

辞書にはsortメソッドがありません。辞書を並べ替えたい場合は、d.keys()d.items()などのビューをsortedして、その結果を必要なら辞書へ組み直します。

Python
d = {"b": 2, "a": 1, "c": 3}

# sorted(d) はキーを並べ替える
print(sorted(d))          # ['a', 'b', 'c']

# items()をsortedして(キー, 値)の並んだリストにする
print(sorted(d.items()))  # [('a', 1), ('b', 2), ('c', 3)]

# list.sortはリスト専用で戻り値None
pairs = list(d.items())
print(pairs.sort() is None)  # True
print(pairs)                 # インプレースでソート済み
実行結果
['a', 'b', 'c']
[('a', 1), ('b', 2), ('c', 3)]
True
[('a', 1), ('b', 2), ('c', 3)]

まとめ

辞書は挿入順を保持しますが、辞書自体を直接ソートすることはできません。

並べ替えはsortedを使い、対象にd(キー)、d.values()(値)、d.items()(項目)のいずれを渡すかを選び、key引数で比較基準を設計します。

キー基準ならsorted(d.items())、値基準ならkey=lambda kv: kv[1]itemgetter(1)、絶対値や大文字小文字無視などのカスタム要件にも柔軟に対応できます。

結果を辞書として利用したい場合は、その順で再構築すれば挿入順が反映されます。

安定ソートを活かした複数基準の並べ替えや、reverse=Trueによる降順指定も含め、基本パターンを押さえておけば実務の大半をシンプルに解決できます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!