2016年6月4日土曜日

Pythonで辞書入りリストを複数キー、複数並び順でソートしてみた

久々にPython書いたのでメモ。
やりたかったのは、辞書が入ってるリストを、辞書の値で並べ替える、というただそれだけのこと。
ただ、キーが複数あってそれぞれ並び順の指定が降順だったり昇順だったりでけっこう苦労した。
全部昇順、全部降順だったら簡単だったんだけど。
まぁ詳細はコードで。
# -*- coding: utf-8 -*-
from operator import itemgetter
scoreList = [
    {'date': '2016-03', 'score': 100, 'subject': 'English'},
    {'date': '2016-03', 'score': 70, 'subject': 'Mathematics'},
    {'date': '2016-03', 'score': 80, 'subject': 'Japanese'},
    {'date': '2015-03', 'score': 90, 'subject': 'English'},
    {'date': '2015-03', 'score': 60, 'subject': 'Mathematics'},
    {'date': '2015-03', 'score': 70, 'subject': 'Japanese'},
]
print scoreList
# 一般的なやり方だけど、昇順or降順のソートしかできない
sortedList = sorted(scoreList, key=itemgetter('date', 'score'), reverse=True)
print '----------'
print sortedList
# 日付の昇順、点数の降順でソートしたい場合
newSortedList = sorted(scoreList, key=itemgetter('score'), reverse=True)  # 先に第二キーでソート
newSortedList = sorted(newSortedList, key=itemgetter('date'), reverse=False)  # 第一キーでソート(reverseは省略可)
print '----------'
print newSortedList
こんな感じ。
itemgetterで複数のキーを指定できるのはすぐに見つかったんだけど、それだと昇順降順片方しか指定できない。
ならばと第一キーでソートして、第二キーでソートすればいけるかというと、最初のソートが崩れてしまって全然ダメ。

じゃあどうしよっか、と思ってググってたら英語の質問掲示板みたいなところ(stackoverflowではない)で上のやり方が紹介されてたので、やってみたらできた。
キーが増えれば増えるほどコードが増えていって微妙だけど、まぁこれでいっか、という感じ。
他に良いやり方があればご教示頂きたいです。

ちなみに上のコード、プレビューで見たら長いコードは折り返しできなくて右メニューを突き抜けてて微妙だった。。
後で確認しよう。