Pythonで2次元配列(リストのリスト)をソート

Pythonで2次元配列(リストのリスト)をsort()メソッドやsorted()関数で任意の要素に従ってソートする方法を説明します。 NumPyを使っても同様の処理ができます。NumPyを使うと各列・各行をそれぞれソートしたりすることもできます。詳細は

ここではNumPyを使わずPython標準の関数やメソッドで処理する方法について説明します。

リストオブジェクトの大小比較 2次元配列(リストのリスト)のソート 引数keyに無名関数(ラムダ式)を指定 引数reverseで降順・昇順を指定 sort()メソッドでもsorted()関数でも同様 多次元配列でも同様

同様の方法で辞書のリストを特定のキーの値に従ってソートできます。

出力を見やすくするためpprintモジュールを使っています。

import pprint

リストオブジェクトの大小比較

Pythonにおけるリストオブジェクトの大小比較は、最初の等しくない要素に対して行われる。

Collections that support order comparison are ordered the same as their first unequal elements (for example, [1,2,x] <= [1,2,y] has the same value as x <= y). If a corresponding element does not exist, the shorter collection is ordered first (for example, [1,2] < [1,2,3] is true).
6.(expression) — Python 3.6.5 ドキュメント

print([100] > [-100])
# True

print([1, 2, 100] > [1, 2, -100])
# True

print([1, 2, 100] > [1, 100])
# False

2次元配列(リストのリスト)のソート

以下の2次元配列(リストのリスト)を例とします。

l_2d = [[2, 30, 100], [1, 20, 300], [3, 10, 200]]

pprint.pprint(l_2d, width=40)
# [[2, 30, 100],
#  [1, 20, 300],
#  [3, 10, 200]]

sort()メソッドやsorted()関数でソートする場合、デフォルトでは各リストが比較されソートされます。上述のように、リスト同士の比較は最初の等しくない要素に対して行われる。 この例では、各リストの最初の要素同士が比較されソートされます。

l_2d.sort()

pprint.pprint(l_2d, width=40)
# [[1, 20, 300],
#  [2, 30, 100],
#  [3, 10, 200]]

引数keyに無名関数(ラムダ式)を指定

任意の要素に従ってソートしたい場合は、sort()メソッドやsorted()関数の引数keyに無名関数(ラムダ式)を指定します。 keyには、ソートされる(各要素が比較される)前にリストの各要素に適用される関数を指定します。keyに指定した関数の結果に従ってソートされます。 今回の例ではリストの要素であるリストから任意の要素を取得する関数を指定すればOKです。 def文で関数を定義してもいいが、このような場合は無名関数(ラムダ式)を使うと便利です。

l_2d.sort(key=lambda x: x[1])

pprint.pprint(l_2d, width=40)
# [[3, 10, 200],
#  [1, 20, 300],
#  [2, 30, 100]]

無名関数(ラムダ式)についての詳細は

この例では2次元配列の任意の列の値に従って行を並べ替えるが、行の値に従って列を並べ替えたい場合は先に転置してソートしたあとさらに転置すればOKです。

列を並べ替えたい場合、NumPyを使える環境であればNumPyを使ったほうが楽。

引数reverseで降順・昇順を指定

降順・昇順は引数reverseで指定します。

l_2d.sort(key=lambda x: x[2], reverse=True)

pprint.pprint(l_2d, width=40)
# [[1, 20, 300],
#  [3, 10, 200],
#  [2, 30, 100]]

sort()メソッドでもsorted()関数でも同様

これまでの例はリストのメソッドsort()を使っているが、組み込み関数sorted()でも同様に引数keyや引数reverseを指定できます。

l_sorted = sorted(l_2d, key=lambda x: x[0], reverse=True)

pprint.pprint(l_sorted, width=40)
# [[3, 10, 200],
#  [2, 30, 100],
#  [1, 20, 300]]

sort()とsorted()の違いについては

多次元配列でも同様

ここれまでの例は2次元配列だが、3次元以上の多次元配列でも同じです。 引数keyでの指定を形状に合わせて変更すれば問題ありません。

l_3d = [[[0, 1, 2], [2, 30, 100]], [[3, 4, 5], [1, 20, 300]], [[6, 7, 8], [3, 10, 200]]]

pprint.pprint(l_3d, width=40)
# [[[0, 1, 2], [2, 30, 100]],
#  [[3, 4, 5], [1, 20, 300]],
#  [[6, 7, 8], [3, 10, 200]]]

l_sorted = sorted(l_3d, key=lambda x: x[1][0])

pprint.pprint(l_sorted, width=40)
# [[[3, 4, 5], [1, 20, 300]],
#  [[0, 1, 2], [2, 30, 100]],
#  [[6, 7, 8], [3, 10, 200]]]
Last Updated: 6/26/2019, 10:34:03 PM