Python
AdventCalendar
Python3
Python2

itemgetter/attrgetterでsortedのkeyをスッキリさせる

この記事は Pythonのコードを短く簡潔に書くテクニック Advent Calendar 2017 の3日目です。

はじめに

sorted関数やlistのsortメソッドでソートキーを指定するには、引数keyにソートキーを取得する関数を指定します。
keyはラムダ式で書くことが多いですが、特定の条件ではitemgetterattrgetterを使うとスッキリ書くことができます。

itemgetter

指定インデックスの値を取得する関数を作成します。
listやdictのような[]で要素を指定するオブジェクトから値を取得するのに使用します。

ソート対象データ
values = [
    {'name': 'tarou', 'kokugo': 60, 'sansuu': 70},
    {'name': 'jirou', 'kokugo': 90, 'sansuu': 70},
    {'name': 'hanako', 'kokugo': 60, 'sansuu': 30},
]
ラムダ式を使う場合
sorted(values, key=lambda x: (x['kokugo'], x['sansuu'],), reverse=True)
# [{'name': 'jirou', 'kokugo': 90, 'sansuu': 70}, 
#  {'name': 'tarou', 'kokugo': 60, 'sansuu': 70}, 
#  {'name': 'hanako', 'kokugo': 60, 'sansuu': 30}]
itemgetterを使う場合
from operator import itemgetter
sorted(values, key=itemgetter('kokugo', 'sansuu'), reverse=True)
# [{'name': 'jirou', 'kokugo': 90, 'sansuu': 70}, 
#  {'name': 'tarou', 'kokugo': 60, 'sansuu': 70}, 
#  {'name': 'hanako', 'kokugo': 60, 'sansuu': 30}]

attrgetter

指定属性の値を取得する関数を作成します。
obj.attrのように.で属性を指定するオブジェクトから値を取得するのに使用します。

ソート対象データ
from datetime import date
values = [
    date(2017, 12, 1),
    date(2015, 11, 3),
    date(2016, 10, 3),
]
ラムダ式を使う場合
sorted(values, key=lambda x: (x.month, x.day,))
# [datetime.date(2016, 10, 3), 
#  datetime.date(2015, 11, 3), 
#  datetime.date(2017, 12, 1)]
attrgetterを使う場合
>>> from operator import attrgetter
>>> sorted(values, key=attrgetter('month', 'day'))
[datetime.date(2016, 10, 3), datetime.date(2015, 11, 3), datetime.date(2017, 12, 1)]

参考