hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
11/28/2013 うむ [長年日記]
tDiary 4053日目
■ [Py][メモ] 辞書のリストを色んな型でソート
タイトルだけではなんのこっちゃという感じかもだけど,要はこういうこと.これを key1, 2, 3 で複合的にそれっぽくソートしてみる.
iterable = ( { 'key1': '1', 'key2': '192.168.0.2', 'key3': 'あいう', 'val': 'hoge', }, { 'key1': '0x0e', 'key2': '192.168.0.22', 'key3': 'えおか', 'val': 'hage', }, { 'key1': '0x0e', 'key2': '192.168.0.3', 'key3': 'きくけ', 'val': 'hige', }, { 'key1': '1', 'key2': '192.168.1.20', 'key3': 'こさし', 'val': 'huge', }, { 'key1': '1', 'key2': '192.168.0.2', 'key3': 'すせそ', 'val': 'hege', }, )
ソート HOWTO を読むと operator.itemgetter が何やらそれっぽいのだけれど,残念ながら (当然ながら) 文字列に対しては文字列的にしかソートできない ("1" -> "11" -> "2" になる).
itemgetter の内部処理を外部的にいじくる良い方法は思いつかないので,こんな関数を作ってみる.
def itemgetter2(*items): def g(obj): return tuple(item[1](obj[item[0]], *item[2:]) for item in items) return g
で,こんな風に呼んでみる.
import socket import locale result = sorted(iterable, key=itemgetter2(('key1', int, 16), ('key2', socket.inet_aton), ('key3', locale.strxfrm)))
結果は下記の通り.めでたしめでたし.
[{'key1': '1', 'key2': '192.168.0.2', 'key3': 'あいう', 'val': 'hoge'}, {'key1': '1', 'key2': '192.168.0.2', 'key3': 'すせそ', 'val': 'hege'}, {'key1': '1', 'key2': '192.168.1.20', 'key3': 'こさし', 'val': 'huge'}, {'key1': '0x0e', 'key2': '192.168.0.3', 'key3': 'きくけ', 'val': 'hige'}, {'key1': '0x0e', 'key2': '192.168.0.22', 'key3': 'えおか', 'val': 'hage'}]