リスト.sort() / リスト.reverse() / リスト.copy()
| 対応: | sort() / reverse() | Python 2(2000) |
|---|---|---|
| copy() | Python 3.3(2012) |
リストを並べ替えたり、順序を逆にしたり、コピーを作成するメソッドです。元のリストを直接変更する点が特徴です。
構文
# リストをその場でソートする(戻り値は None) リスト.sort(key=None, reverse=False) # リストの要素の順序を反転する(戻り値は None) リスト.reverse() # リストの浅いコピーを返す リスト.copy() # sorted() は元のリストを変更せず新しいリストを返す sorted(イテラブル, key=None, reverse=False)
関数一覧
| メソッド・関数 | 概要 |
|---|---|
| list.sort(key, reverse) | リストをその場で(in-place)ソートします。元のリストが変更されます。戻り値は None です。 |
| list.reverse() | リストの要素の順序をその場で逆転させます。元のリストが変更されます。戻り値は None です。 |
| list.copy() | リストの浅いコピー(shallow copy)を返します。list[:] と同じ効果です。 |
| sorted(iterable, key, reverse) | 元のイテラブルを変更せず、ソートされた新しいリストを返します。リスト以外にも使えます。 |
サンプルコード
list_sort_reverse_1.py
# sort() でリストをその場でソートする scores = [75, 42, 98, 61, 88] scores.sort() print(scores) # [42, 61, 75, 88, 98] # reverse=True で降順にソートする scores.sort(reverse=True) print(scores) # [98, 88, 75, 61, 42]
実行すると次のように出力されます。
python3 list_sort_reverse_1.py [42, 61, 75, 88, 98] [98, 88, 75, 61, 42]
list_sort_reverse_2.py
# key 関数を指定してカスタムソートする
members = ["product_x", "member_ab", "item_a", "ex"]
members.sort(key=len)
print(members) # ['ex', 'item_a', 'member_ab', 'product_x']
# 辞書のリストをキーでソートする
staff = [
{"name": "member_a", "score": 170},
{"name": "member_b", "score": 190},
{"name": "member_c", "score": 155},
]
staff.sort(key=lambda m: m["score"])
print(staff[0]["name"]) # member_c
実行すると次のように出力されます。
python3 list_sort_reverse_2.py ['ex', 'item_a', 'member_ab', 'product_x'] member_c
list_sort_reverse_3.py
# sorted() は元のリストを変更しない
members = ["product_x", "member_ab", "item_a", "ex", "data_01"]
sorted_members = sorted(members)
print(members) # 元のリストは変わりません
print(sorted_members) # ソートされた新しいリスト
# copy() でリストのコピーを作成する
original = ["member_a", "member_b"]
copied = original.copy()
copied.append("member_c")
print(original) # ['member_a', 'member_b']
print(copied) # ['member_a', 'member_b', 'member_c']
# reverse() でリストの順序を逆にする
members.reverse()
print(members)
実行すると次のように出力されます。
python3 list_sort_reverse_3.py ['product_x', 'member_ab', 'item_a', 'ex', 'data_01'] ['data_01', 'ex', 'item_a', 'member_ab', 'product_x'] ['member_a', 'member_b'] ['member_a', 'member_b', 'member_c'] ['data_01', 'ex', 'item_a', 'member_ab', 'product_x']
よくあるミス
よくあるミス1: sort() の戻り値を変数に代入する
sort() はリストをその場で変更し、戻り値は None です。戻り値を変数に代入すると None が入ります。元のリストを変更せずにソートしたい場合は sorted() を使います。
members = ["member_c", "member_a", "member_b"] result = members.sort() print(result) # None(sort() の戻り値は None)
次のように記述します。
members = ["member_c", "member_a", "member_b"] result = sorted(members) print(result) # ['member_a', 'member_b', 'member_c'](新しいリスト)
よくあるミス2: copy() でネストしたリストを完全コピーしようとする
copy() は浅いコピー(shallow copy)です。リストの要素が別のリストや辞書の場合、内部のオブジェクトはコピーされずに参照が共有されます。完全なコピーが必要な場合は copy.deepcopy() を使うことで深いコピーが得られます。
original = [["member_a", 170], ["member_b", 190]] copied = original.copy() copied[0][1] = 999 # 内部リストへの参照が共有されている print(original[0][1]) # 999(元のリストも変わってしまう)
次のように記述します。
import copy original = [["member_a", 170], ["member_b", 190]] copied = copy.deepcopy(original) copied[0][1] = 999 print(original[0][1]) # 170(元のリストは変わらない)
概要
『sort()』と『sorted()』の大きな違いは、元のリストを変更するかどうかです。『sort()』は元のリストをその場で変更し、戻り値は None です。ソート後のリストを新しい変数に代入しようとすると None が入ってしまいます。元のリストを保持したい場合は『sorted()』を使うと元のリストを変更せずに済みます。
Pythonのソートアルゴリズムには Timsort が使われており、安定ソート(同じ値の要素の相対的な順序が保たれる)です。これにより、複数のキーで段階的にソートする(最初に名前でソート、次にスコアでソート)ようなことが期待通りに動作します。
『copy()』は浅いコピー(shallow copy)を作成します。リストの要素が別のリストや辞書などのオブジェクトの場合、そのオブジェクト自体はコピーされずに参照が共有されます。完全なコピーが必要な場合は『copy.deepcopy()』を使うことで深いコピーが得られます。スライスによるコピーや結合については『リストのスライス』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。