【Python入門】list sortでリストの中身を効率的にソートする方法

※こちらの記事は、プロスタ編集部が現在大変人気の高いPythonの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。

参考サイト：[【Python入門】list sortでリストの中身を効率的にソートする方法](http://programming-study.com/technology/python-list-sort/)


#【Python入門】list sortでリストの中身を効率的にソートする方法

プログラミングをしていると、リストの中身をソートしたい場面が出てきます。言語によってはfor文などを駆使して、既存のソートアルゴリズムを実現する、というやり方のものがあり、意外と大変です。しかし、Pythonならリストをソートするための関数が用意されているため、簡単にソートすることができます。

今回は、リストの中身をソートする方法を説明します。

目次 
1 [sort関数を使ったソート](##sort関数を使ったソート)
2 [reverse関数を使った逆順ソート](##reverse関数を使った逆順ソート)
3 [sorted関数を使ったソート](##sorted関数を使ったソート)
　　　3.1 [sorted関数で昇順ソート](###sorted関数で昇順ソート)
　　　3.2 [sorted関数で降順ソート](###sorted関数で降順ソート)
4 [多次元リストのソート](##多次元リストのソート)


##sort関数を使ったソート

Pythonでリストをするためのもっとも簡単な方法はsort関数を使うことです。sort関数の構文は以下のようになります。

```
リスト.sort()
```

sort()を使うと、リストの中身が昇順でソートされます。文字列は文字コード順、数値は小さい順にソートされます。sort()でソートした場合は、元のリストの中身が入れ替わります。

```
list1 = ['python', 'list', 'sort']
print('ソート前：{}'.format(list1))
 
list1.sort()
print('ソート後：{}'.format(list1))
```

実行結果

>ソート前：[‘python’, ‘list’, ‘sort’]
ソート後：[‘list’, ‘python’, ‘sort’]

##reverse関数を使った逆順ソート

sort関数を使えば、リストを簡単にソートできますが、順番が必ず昇順になります。降順でソートしたいときはreverse関数を使いましょう。reverse関数の構文は以下の通りです。

```	
リスト.reverse()
```
reverse()を使うと、リストの中身がすべて逆順になります。そのため、sort()を使って昇順にソートした後にreverse()を使うことで、リストを降順にソートすることができます。

```
list1 = [1,5,3,9,6,7,8]
print('ソート前：{}'.format(list1))
 
list1.sort()
print('ソート後(昇順)：{}'.format(list1))
 
list1.reverse()
print('ソート後(降順)：{}'.format(list1))
```

実行結果

>ソート前：[1, 5, 3, 9, 6, 7, 8]
ソート後(昇順)：[1, 3, 5, 6, 7, 8, 9]
ソート後(降順)：[9, 8, 7, 6, 5, 3, 1]

##sorted関数を使ったソート

sort関数でリストを昇順ソート、さらにreverse関数を使うことで降順ソートが実現できることが分かりました。しかし、この2つの関数を使ったソートの場合は、元のリストの中身が書き換えられます。

ソートをしたけど元に戻しておきたい場合などを考えると、できれば中身は変えずにソート済みのリストを新しく別に作成したい、という場合あります。そんな時はsorted関数が便利です。

###sorted関数で昇順ソート

sorted関数は、sort関数と同様にリストをソートする関数です。しかし、sorted関数はソートされたリストを返すので、sort関数とは違って元のソートの中身は変わりません。sorted関数で昇順ソートを行う構文は以下のようになります。

```
リスト2 = sorted(リスト１)
```

ソートする前のリスト1をsortedに渡すことで、ソートされたリストが返されます。それをリスト2に代入することで、リスト1をソートした新しいリスト2が作られます。元のリストは変更されないので、もしもの時に備えて元のリストをのこしておけるのはいいですね。

```
list1 = [1,5,3,9,6,7,8]
list2 = sorted(list1)
 
print('ソート前：{}'.format(list1))
print('ソート後：{}'.format(list2))
```

実行結果

>ソート前：[1, 5, 3, 9, 6, 7, 8]
ソート後：[1, 3, 5, 6, 7, 8, 9]


##sorted関数で降順ソート

sorted関数でソートを行うと昇順になりますが、当然降順にソートすることもできます。

```
リスト2 = sorted(リスト１)
```

sorted関数を使う際に、reverseというオプションをTrueにすることで、降順にソートすることができます。

```
list1 = [1,5,3,9,6,7,8]
list2 = sorted(list1, reverse=True)  #reverseをTrueに

print('ソート前：{}'.format(list1))
print('ソート後：{}'.format(list2))
```

実行結果

>ソート前：[1, 5, 3, 9, 6, 7, 8]
ソート後：[9, 8, 7, 6, 5, 3, 1]
多次元リストのソート

ここまで1次元のリストのソートの方法を説明してきましたが、時には2次元以上の多次元リストをソートしたい場合があると思います。多次元の配列でも1次元と同様にsort(), reverse(), sorted()を使えばソートできます。

しかし、多次元の場合はどの値をキーにしてソートしたかによって結果が変わります。例えば、以下のようなリストをソートするとします。

```
list1 = [[1,5,3], [6,4,8], [9,11,2]]
```

このlist1は3個の要素を持つリストが3つ集まった2次元配列です。このlist1は、要素となっている各リストの何番目の要素をキーにするかでソートの結果が変わります。

```
[[1, 5, 3], [6 ,4 ,8], [9, 11, 2]]  #各リストの1番目の要素をキー
[[6, 4, 8], [1, 5, 3], [9, 11, 2]]  #各リストの2番目の要素をキー
[[9, 11, 2], [1, 5, 3], [6, 4, 8]]  #各リストの3番目の要素をキー
```

多次元リストを普通にソートすると1番目の要素をキーにしてソートされます。キーにする要素を指定してソートするには、itemgetterを使用します。

```
from operator import itemgetter

リスト1.sort(key=itemgetter(1)) #リスト1は2次元以の配列
```

itemgetterはoperatorライブラリの関数なので、最初にインポートする必要があります。itemgetter()の引数は、キーにしたい要素の番号を表します。itemgetter(1)の場合は1番目の要素をキーにしてリストをソートします。

itemgetterを使うことで、どの要素をキーにするかを選択することができます。

```
from operator import itemgetter
 
list1 = [[1,5,3], [6,4,8], [9,11,2]]
print('ソート前：{}'.format(list1))
 
list1.sort(key=itemgetter(0))
print('ソート後(0番目の要素)：{}'.format(list1))
 
list1.sort(key=itemgetter(1))
print('ソート後(1番目の要素)：{}'.format(list1))
 
list1.sort(key=itemgetter(2))
print('ソート後(2番目の要素)：{}'.format(list1))
```

実行結果

>ソート前：[[1, 5, 3], [6, 4, 8], [9, 11, 2]]
ソート後(0番目の要素)：[[1, 5, 3], [6, 4, 8], [9, 11, 2]]
ソート後(1番目の要素)：[[6, 4, 8], [1, 5, 3], [9, 11, 2]]
ソート後(2番目の要素)：[[9, 11, 2], [1, 5, 3], [6, 4, 8]]