pythonで、辞書をまとめたリストをソートする、重複排除(制限あり)

2012-03-22(Thu) python

例えばpythonでこういうデータを使う時に(例のセンスが無いのはご了承を)

[python]
data = [{"summary":u"insert testdata1","date":{"created":u"2012-01-01"}},
{"summary":u"insert testdata2","date":{"created":u"2012-01-02"}},
{"summary":u"insert testdata3","date":{"created":u"2012-01-03"}},
{"summary":u"insert testdata1","date":{"created":u"2012-01-01"}},
{"summary":u"insert testdata2","date":{"created":u"2012-01-02"}},
{"summary":u"insert testdata2","date":{"created":u"2012-01-02"}},
{"summary":u"insert testdata2","date":{"created":u"2012-01-02"}},
]
[/python]

辞書をデータの構造にして、それをリストでまとめてあるイメージです
ソートしたい時は
[python]
>>> keyfunc = lambda x:x["date"]["created"]
>>> sorted_data = sorted(data, key=keyfunc)

>>> sorted_data

stdout

[{'date': {'created': u'2012-01-01'}, 'summary': u'insert testdata1'},
{'date': {'created': u'2012-01-01'}, 'summary': u'insert testdata1'},
{'date': {'created': u'2012-01-02'}, 'summary': u'insert testdata2'},
{'date': {'created': u'2012-01-02'}, 'summary': u'insert testdata2'},
{'date': {'created': u'2012-01-02'}, 'summary': u'insert testdata2'},
{'date':{'created': u'2012-01-02'}, 'summary': u'insert testdata2'},
{'date': {'created': u'2012-01-03'}, 'summary': u'insert testdata3'}]

[/python]
です。

重複なしのユニークにしたい時は、set関数(型)があるそうですがこの形では使えません。
[python]

ipythonのコンソール

In [13]: set(sorted_data)

TypeError Traceback (most recent call last)

[console_path]\\<ipython console> in \<module>()

TypeError: unhashable type: 'dict'
[/python]

そこで、itertoolsモジュールのgroupbyメソッド(メソッドと読んで良い?)を使ってみました。
groupbyとはこういうものです。
9.7. itertools — 効率的なループ実行のためのイテレータ生成関数 — Python 2.7ja1 documentation

keyを指定して、その部分が同じ要素をグループ化してくれます。なので、要素のある一部を重複判定に使っているイメージです。
今回の例は、辞書内の["data"]["created"]をキーにしています。

[python]

python documentationに乗ってる例をほぼそのまま使っています

>>> import itertools

上のソートと同じ

>>> keyfunc = lambda x:x["date"]["created"]
>>> data = sorted(data, key=keyfunc)

>>> unique_data = []
>>> for k, g in itertools.groupby(data, keyfunc):
... unique_data.append(g.next())

print unique_data

stdout

[{'date': {'created': u'2012-01-01'}, 'summary': u'insert testdata1'},
 {'date': {'created': u'2012-01-02'}, 'summary': u'insert testdata2'},
 {'date': {'created': u'2012-01-03'}, 'summary': u'insert testdata3'},]

[/python]

このメソッドを本来こうやって使うのが良いのかどうなのかはわかりませんが、これで乗り切ってしまってます(汗
この他に良い方法があったら教えて下さい!