python の dict をソート
python|3の dict のソートで次のようなコード片を紹介されてることが多いが、これは厳密には「辞書のソート」ではない。 という重箱記事である。
score_sorted = sorted(score.items(), key=lambda x:x[0])
詳細には次の通り。
- dict を key/value の Iterable [ Tuple [ Any,Any ] ] で取り出し、
- tupleの0番目、すなわちkeyでの比較を指定して ( key = callable )
- sort する
つまり、処理は「辞書の「中身」をソート」である。
が、これには dict の仕様上の問題もある。 dict自体はソートの概念をもたないためだ。(dictを始めとした俗に言う hash は本来そういうものだ)
listには明確な順序があるため。 sort ができる。
sorted() / list.sort() 等の手段があるが、この場合は items() : iterable からの入力なので必然 sorted()を使わざるをえなくなる。
結果は List[Tuple[Any,Any]] となる。これはもちろん dict の全機能が使えなくなる。 だが、判っててやってるならもちろん問題はない。
この出力を dict() に突っ込めば、キーソート済の新しい dict が手に入る。
dict 自身にはソートの機能をもたないが、python3.7より挿入時の登録順を維持するようになったため、ソート済のまま使えはするといった寸法だ。
なお、この例示のように、「tupleのn番目を取り出したい」程度の話であれば、標準ライブラリが存在する。
operator — Standard operators as functions — Python 3.10.8 documentation
まとめるとこうなる。
from operator import itemgetter
sorted_dict = dict(sorted(score.items(), key=itemgetter(0)))
lambda に対して、文字数も若干特をしてる....(import は除く)
小生であれば、これで十分に simple だと思ってるが、世の中にはコード文字数が短いほうが正義だと思ってる流派があるようだ。残念ながらそういう手合いにはお気に召さないかもしれない。
Discussion