Help us understand the problem. What is going on with this article?

Pythonソートチートシート

More than 3 years have passed since last update.

ソート 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
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした