note.nkmk.me

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

Date: 2018-05-03 / tags: Python, リスト

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に指定した関数の結果に従ってソートされる。

今回の例ではリストの要素であるリストから任意の要素を取得する関数を指定すればよい。

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次元配列の任意の列の値に従って行を並べ替えるが、行の値に従って列を並べ替えたい場合は先に転置してソートしたあとさらに転置すればよい。

列を並べ替えたい場合、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での指定を形状に合わせて変更すればOK。

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]]]
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事