Pythonソートチートシート

この記事は最終更新日から3年以上が経過しています。

ソート 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]

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

tag1216
Qiita戦闘力はキュイレベルです! /作ったもの ◆QiiTrend:https://qiitrend.herokuapp.com/ ◆Qiiner:https://qiiner.tag1216.net/ ◆Qiitaでいいねしたら草生えるページ:https://qiiner.tag1216.net/likes-heatmap
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした