🤖

python の dict をソート

2022/12/20に公開約1,100字

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

ログインするとコメントできます