LoginSignup
51

More than 5 years have passed since last update.

Pythonソートチートシート

Last updated at Posted at 2016-09-20

ソート HOW TO — Python 3.5.1 ドキュメント の内容と、追加のTIPSです。

ソート関数

list.sort()

  • リストをソートして元のリストを置き換える。
  • 戻り値はない。
>>> a = [3, 0, 5, 1]
>>> a.sort()
>>> a
[0, 1, 3, 5]
>>> print(a.sort())  # 戻り値はない
None

sorted(list)

  • リストをソートした結果を返す。
  • 元のリストは変更されない。
  • リスト以外にも使える。
>>> a = [3, 0, 5, 1]
>>> sorted(a)
[0, 1, 3, 5]
>>> a  # 元のリストは変更されない
[3, 0, 5, 1]
>>> sorted(iter([3, 0, 5, 1]))  # リスト以外にも使える
[0, 1, 3, 5]

逆順ソート

  • reverse=Trueを指定する。
>>> a = [3, 0, 5, 1]
>>> sorted(a, reverse=True)
[5, 3, 1, 0]

ソートキーを指定する

  • keyに関数やラムダ式を指定する。
>>> a = ["c", "aaa", "Bb"]
>>> sorted(a, key=lambda x: x.lower())
['aaa', 'Bb', 'c']
>>> sorted(a, key=str.lower)
['aaa', 'Bb', 'c']
>>> sorted(a, key=len)
['c', 'Bb', 'aaa']

辞書・リスト・タプルを要素に持つリストのソート

  • デフォルトでは要素を順に比較してくれる。
>>> a = [("b", 3), ("b", 1), ("a", 1), ("a", 2), ("c", 2)]
>>> sorted(a)
[('a', 1), ('a', 2), ('b', 1), ('b', 3), ('c', 2)]
  • キーを指定する場合はitemgetterを使用するとラムダ式より簡潔。
>>> a = [{"key1": 3}, {"key1": 1}]
>>> from operator import itemgetter
>>> sorted(a, key=itemgetter("key1"))
[{'key1': 1}, {'key1': 3}]

クラスを要素に持つリストのソート

  • キーを指定する場合はattrgetterを使用するとラムダ式より簡潔。
>>> from datetime import date
>>> a = [date(2016, 1, 1), date(2015, 12, 1)]
>>> from operator import attrgetter
>>> sorted(a, key=attrgetter("month"))
[datetime.date(2016, 1, 1), datetime.date(2015, 12, 1)]

複合ソート

  • ソート結果に対して更にソートをすれば複合ソートができる。
  • 優先度の低いキーから先にソートしていく。
>>> a = [("b", 3), ("b", 1), ("a", 1), ("a", 2), ("c", 2)]
>>> b = sorted(a, key=itemgetter(1), reverse=True)
>>> sorted(b, key=itemgetter(0))
[('a', 2), ('a', 1), ('b', 3), ('b', 1), ('c', 2)]
  • itemgetterとattrgetterは一度に複数キーを指定できるので、降順・昇順が全てのキーで同じならこちらを使う。
>>> sorted(a, key=itemgetter(0, 1))
[('a', 1), ('a', 2), ('b', 1), ('b', 3), ('c', 2)]

Noneを含む場合のソート

  • 普通にソートすると失敗する。
  • 複合ソートとして第一キーにNoneかどうかのbool、第二キーに要素自身を指定する。
>>> a = [3, 0, None, 5, 1]
>>> sorted(a)  # 普通にソートすると失敗
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()
>>> sorted(a, key=lambda x: (x is None, x))  # Noneを末尾に
[0, 1, 3, 5, None]
>>> sorted(a, key=lambda x: (x is not None, x))  # Noneを先頭に
[None, 0, 1, 3, 5]

Python sort list with None at the end - Stack Overflow

クラスをソート可能にする

  • __lt__()を実装しておく。
class P(object):
    def __init__(self, gender, age):
        self.gender = gender
        self.age = age
    def __repr__(self):
        return "{:s}{:d}".format(self.gender, self.age)
    def __lt__(self, other):
        return (self.gender, self.age) < (other.gender, other.age)

a = [P("F", 30), P("F", 20), P("M", 20), P("M", 40), P("F", 10)]
print(sorted(a))

複数のソートされたiterablesをマージする

>>> import heapq
>>> list(heapq.merge([1, 3, 4, 7], [2, 5], [6]))
[1, 2, 3, 4, 5, 6, 7]

巨大なテキストファイルをソートする

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51