トップ 最新 追記

本 日 の h o g e

hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。

更新情報の取得には rdflirs を使ってもらえると嬉しいです.


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'}]