Pythonのsorted()で二次元リスト・二次元辞書・辞書リストをソートする

わりと使うのにすぐ忘れてしまう。

二次元リストをsorted()でソート

from operator import itemgetter
from pprint import pprint

d = [
    [2, 'c', 'は'],
    [1, 'b', 'い'],
    [2, 'a', 'ろ']
]

pprint(sorted(d), width=20)
# [[1, 'b', 'い'],
#  [2, 'a', 'ろ'],
#  [2, 'c', 'は']]

# 降順ソート
pprint(sorted(d, reverse=True), width=20)
# [[2, 'c', 'は'],
#  [2, 'a', 'ろ'],
#  [1, 'b', 'い']]

# 各リスト2番目の要素でソート
pprint(sorted(d, key=lambda x: x[1]), width=20)
# [[2, 'a', 'ろ'],
#  [1, 'b', 'い'],
#  [2, 'c', 'は']]

# 1番目の要素でソートして等しい場合には3番目の要素でソート
pprint(sorted(d, key=lambda x: (x[0], x[2])), width=20)
# [[1, 'b', 'い'],
#  [2, 'c', 'は'],
#  [2, 'a', 'ろ']]

# またはoperator.itemgetter()を使って
pprint(sorted(d, key=itemgetter(0, 2)), width=20)
# [[1, 'b', 'い'],
#  [2, 'c', 'は'],
#  [2, 'a', 'ろ']]

# 1番目の要素で降順ソートして等しい場合には2番目の要素で昇順ソート
d2 = sorted(d, key=lambda x: x[1])
pprint(sorted(d2, key=lambda x: x[0], reverse=True), width=20)
# [[2, 'a', 'ろ'],
#  [2, 'c', 'は'],
#  [1, 'b', 'い']]

# 独自のソート定義でソート
od = {'い': 0, 'ろ': 1, 'は': 2}
pprint(sorted(d, key=lambda x: od[x[2]]), width=20)
# [[1, 'b', 'い'],
#  [2, 'a', 'ろ'],
#  [2, 'c', 'は']]

二次元辞書をsorted()でソート

from pprint import pprint

d = {
    'hoge': {
        'num': 2,
        'abc': 'c',
        'kana': 'は'
    },
    'fuga': {
        'num': 1,
        'abc': 'b',
        'kana': 'い'
    },
    'piyo': {
        'num': 2,
        'abc': 'a',
        'kana': 'ろ'
    }
}

pprint(dict(sorted(d.items())), width=20, sort_dicts=False)
# {'fuga': {'num': 1,
#           'abc': 'b',
#           'kana': 'い'},
#  'hoge': {'num': 2,
#           'abc': 'c',
#           'kana': 'は'},
#  'piyo': {'num': 2,
#           'abc': 'a',
#           'kana': 'ろ'}}

# 子辞書のキー'num'でソートして等しい場合には子辞書のキー'abc'でソート
pprint(dict(sorted(d.items(), key=lambda x: (x[1]['num'], x[1]['abc']))), width=20, sort_dicts=False)
# {'fuga': {'num': 1,
#           'abc': 'b',
#           'kana': 'い'},
#  'piyo': {'num': 2,
#           'abc': 'a',
#           'kana': 'ろ'},
#  'hoge': {'num': 2,
#           'abc': 'c',
#           'kana': 'は'}}

辞書リストをsorted()でソート

from pprint import pprint

d = [
  {
    'num': 2,
    'abc': 'c',
    'kana': 'は'
  },
  {
    'num': 1,
    'abc': 'b',
    'kana': 'い'
  },
  {
    'num': 2,
    'abc': 'a',
    'kana': 'ろ'
  }
]

# キー'num'でソート
pprint(sorted(d, key=lambda x: x['num']), width=20, sort_dicts=False)
# [{'num': 1,
#   'abc': 'b',
#   'kana': 'い'},
#  {'num': 2,
#   'abc': 'c',
#   'kana': 'は'},
#  {'num': 2,
#   'abc': 'a',
#   'kana': 'ろ'}]

# キー'num'でソートして等しい場合は独自のソート定義でキー'kana'をソート
od = {'い': 0, 'ろ': 1, 'は': 2}
pprint(sorted(d, key=lambda x: (x['num'], od[x['kana']])), width=20, sort_dicts=False)
# [{'num': 1,
#   'abc': 'b',
#   'kana': 'い'},
#  {'num': 2,
#   'abc': 'a',
#   'kana': 'ろ'},
#  {'num': 2,
#   'abc': 'c',
#   'kana': 'は'}]

環境

参考