Fluent Python という 800ページあるクソ分厚い本を読んでいるのですが、この分厚さからも想像がつくようにたいがい腰を据えてじっくり取り組む感じの本です。 ただ、覚えているとすぐに使えそうな内容にもちょいちょい出会うのでこういう場所にメモ代わりに残していきます。
誰に需要があるかというと、俺。 俺が読む。 以上。
list 型をソートする方法として代表的なものが二つあって、list.sort
メソッドと組み込み関数の sorted(list)
があります。
list.sort
メソッドの方は本書で言うところの「インプレイスでソート」します。
コピーは作成されません。
元の list オブジェクトがそのまま変更されます。
こういう場合の戻り値は None
にすることが Python API 規約らしいです。
元々のオブジェクトが書き換わってるよ!というのを呼び出し元に明示的に伝えるために、新しいオブジェクトを生成しない(戻り値が None
)という仕様にしないといけないということです。
つまりこういうことです。
>>> l = [28, 14, 5, 0, 6, 19] >>> sorted_l = l.sort() >>> sorted_l # None 何も出力されない >>> l [0, 5, 6, 14, 19, 28] # l そのものが書き換わっている
対して組み込み関数の sorted(list)
の場合は元の list は変更されずソートされた新しい list オブジェクトを生成します。
>>> l = [28, 14, 5, 0, 6, 19] >>> sorted_l = sorted(l) >>> sorted_l [0, 5, 6, 14, 19, 28] # ソートされた新しい list が生成される >>> l [28, 14, 5, 0, 6, 19] # 元の list は変更されない
実はこのことをメモに残したかったのではなくて、 sorted(list)
には追加で他に引数がセットできるということをメモしたかったのでいきなり話を移します。
reverse
True
なら昇順、False
なら降順で返す- デフォルトでは
False
>>> l = [28, 14, 5, 0, 6, 19] >>> sorted_l = sorted(l, reverse=True) >>> sorted_l [28, 19, 14, 6, 5, 0] # 降順で返す
key
- ソートするオプションを指定する
- デフォルトでは
identity
関数(普通に比較する)
>>> l = ['hoge', 'foo', 'obama', 'fuga'] >>> sorted(l, key=len) ['foo', 'hoge', 'fuga', 'obama'] # 文字列の長さでソート >>> sorted(l, key=len, reverse=True) ['obama', 'hoge', 'fuga', 'foo'] # 文字列の長さでソートして逆順に
同じ長さの hoge
と fuga
はどちらの順番でソートしようが元の順序を保存します。
んで、key
に int
と str
を指定すると何やら面白いことができそうです。
>>> l = [28, 14, '28', 5, '9', '1', 0, 6, '23', 19] >>> sorted(l) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'str' and 'int' # 当然だけど型が違うと比較はできない >>> sorted(l, key=int) [0, '1', 5, 6, '9', 14, 19, '23', 28, '28'] # int としてみなしたときの順序 >>> sorted(l, key=str) [0, '1', 14, 19, '23', 28, '28', 5, 6, '9'] # str としてみなしたときの順序
何かに使えそうな気がして記事を書き始めたのですが、書いてるうちに何を考えていたのか忘れました。