python で、リストの要素内に複数の項目でソートを行う方法のメモ。
str に文字列、num に数字が入っているデータをソートします。
str の昇順、num の昇順 でソートする場合には、lambda で str、num の順で指定します。
str の昇順、num の昇順 でソートする場合には、lambda で str、num の順で指定します。
str の降順、num の降順 でソートする場合には、reverse=True を指定します。
より自由に比較順を制御する必要がある場合には functools モジュールの cmp_to_key を使います。
比較関数に cmp1 を指定し、str の降順、num の昇順でソート
比較関数に cmp2 を指定し、str の昇順、num の降順でソート
num のソート順に関しては、符号の反転でも実現可能
str に文字列、num に数字が入っているデータをソートします。
data1 = [ {'str': 'a', 'num': 6}, {'str': 'a', 'num': 5}, {'str': 'b', 'num': 4}, {'str': 'b', 'num': 3}, {'str': 'c', 'num': 2}, {'str': 'c', 'num': 1}, ]
str の昇順、num の昇順 でソートする場合には、lambda で str、num の順で指定します。
sorted(data1, key=lambda x: (x['str'], x['num'])) --> [{'str': 'a', 'num': 5}, {'str': 'a', 'num': 6}, {'str': 'b', 'num': 3}, {'str': 'b', 'num': 4}, {'str': 'c', 'num': 1}, {'str': 'c', 'num': 2}]
str の昇順、num の昇順 でソートする場合には、lambda で str、num の順で指定します。
sorted(data1, key=lambda x: (x['num'], x['str'])) --> [{'str': 'c', 'num': 1}, {'str': 'c', 'num': 2}, {'str': 'b', 'num': 3}, {'str': 'b', 'num': 4}, {'str': 'a', 'num': 5}, {'str': 'a', 'num': 6}]
str の降順、num の降順 でソートする場合には、reverse=True を指定します。
sorted(data1, key=lambda x: (x['str'], x['num']), reverse=True) --> [{'str': 'c', 'num': 2}, {'str': 'c', 'num': 1}, {'str': 'b', 'num': 4}, {'str': 'b', 'num': 3}, {'str': 'a', 'num': 6}, {'str': 'a', 'num': 5}]
より自由に比較順を制御する必要がある場合には functools モジュールの cmp_to_key を使います。
from functools import cmp_to_key # str の降順、num の昇順でソート def cmp1(a, b): # str を比較し、比較結果の符号を反転して返す cmp_str = 0 if a['str'] == b['str'] else -1 if a['str'] < b['str'] else 1 if cmp_str != 0: return - cmp_str # a['str'] が一致した場合は、num の比較結果を返す cmp_num = 0 if a['num'] == b['num'] else -1 if a['num'] < b['num'] else 1 return cmp_num # str の昇順、num の降順でソート def cmp2(a, b): # str を比較し、比較結果を返す cmp_str = 0 if a['str'] == b['str'] else -1 if a['str']
比較関数に cmp1 を指定し、str の降順、num の昇順でソート
sorted(data1, key=cmp_to_key(cmp1))) --> [{'str': 'c', 'num': 1}, {'str': 'c', 'num': 2}, {'str': 'b', 'num': 3}, {'str': 'b', 'num': 4}, {'str': 'a', 'num': 5}, {'str': 'a', 'num': 6}]
比較関数に cmp2 を指定し、str の昇順、num の降順でソート
sorted(data1, key=cmp_to_key(cmp2)) --> [{'str': 'a', 'num': 6}, {'str': 'a', 'num': 5}, {'str': 'b', 'num': 4}, {'str': 'b', 'num': 3}, {'str': 'c', 'num': 2}, {'str': 'c', 'num': 1}]
num のソート順に関しては、符号の反転でも実現可能
sorted(data1, key=lambda x: (x['str'], - x['num']), reverse=True) -> [{'str': 'c', 'num': 1}, {'str': 'c', 'num': 2}, {'str': 'b', 'num': 3}, {'str': 'b', 'num': 4}, {'str': 'a', 'num': 5}, {'str': 'a', 'num': 6}]