はじめに
Pythonでのプログラミング中に、「数値を含む文字列のリストを数値順でソートする処理」が必要になり、試行錯誤していました。本来の処理に直接関係ない部分なので、可読性を犠牲にしてでもコンパクトにしたくなり、勉強がてらにラムダ式を使ってみました。シンプルに書けたのでメモとして残します。
ラムダ式
変数に代入して関数として使う方法を使いました。
-
変数名
= lambda引数
:処理
num_in_str = lambda str: [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', str) ]
動作確認
コード
import re
num_in_str = lambda str: [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', str) ]
lists = ['S23', 'S14', 'S7', 'S11', 'S1']
lists.sort(key=num_in_str)
print(lists)
結果
['S1', 'S7', 'S11', 'S14', 'S23']
参考にした情報
数値を含む文字列のリストを数値順でソート (numerical sort, python)
参考にしたコード部分
import re
def atoi(text):
return int(text) if text.isdigit() else text
def natural_keys(text):
return [ atoi(c) for c in re.split(r'(\d+)', text) ]
sorted(l, key=natural_keys)
このコードで私のやりたかったソートが実現できました。natural_keys()
の中で呼ばれるatoi()
部分は他で使わないことから、これをラムダ式にできると思い、1つにまとめてみました。少なくとも私の使い方だと同じ結果になっています。
おわりに
可読性については様々な議論があると思います。この例ではソートのキーに指定できるライブラリ的なものとしてラムダ式にしてみました。ライブラリをimportする場合、関数の中身は見ないですよね。それと同じ使い方で、必要なソースに「目をつぶってコピペして使える1行」になりました。
ソートの動作については、親文字列の中から正規表現で「連続した数字」を見つけて分解し、子文字列と数値の混合リストにしてソートするのですが、詳しくは参考にした記事をご覧ください。