Pythonで数値を含む文字列を正しく並べ替える方法(自然順ソートの実装)
自然順ソート(ナチュラルソート)とは
文字列に含まれる数値を基準に並べ替える手法は、「自然順ソート(natural sort)」または「ヒューマンソート」と呼ばれます。通常の辞書順ソートでは文字が左から1文字ずつ比較されるため、数値部分が人間の感覚とは異なる順序になってしまうことがあります。
例えば、次のようなリストがあるとします。
['Hello1', 'Hello12', 'Hello29', 'Hello2', 'Hello17', 'Hello25']
これを自然な順序で並べ替えた場合、望ましい結果は以下の通りです。
['Hello1', 'Hello2', 'Hello12', 'Hello17', 'Hello25', 'Hello29']
しかし、単純にsort()を呼び出すだけでは、「Hello12」が「Hello2」よりも先に配置されてしまいます。
['Hello1', 'Hello12', 'Hello17', 'Hello2', 'Hello25', 'Hello29']
sort()のkey引数を使った解決方法
この問題を解決するには、Pythonのsort()メソッドが提供するkey引数を活用します。keyには、リストの各要素からソート用の値を計算するための関数を指定できます。
ここでは、正規表現を使って文字列から数値部分を抽出し、「テキスト部分と数値部分の両方」を考慮したソートを行います。具体的には、re.split(r'(\d+)', text)で文字列を「数字以外の部分」と「数字の部分」に分割し、数字の部分はint型に変換して返す仕組みです。
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)]
my_list = ['Hello1', 'Hello12', 'Hello29', 'Hello2', 'Hello17', 'Hello25']
my_list.sort(key=natural_keys)
print(my_list)コードのポイント
- atoi関数:引数が数字のみの文字列であればint型に変換し、それ以外の場合は元の文字列をそのまま返します。これにより、数値同士は数値として、文字列同士は文字列として正しく比較されます。
- natural_keys関数:例えば「Hello12」は
['Hello', '12', '']に分割され、['Hello', 12, '']というリストがソートキーとして生成されます。 - 生文字列 r'(\d+)':raw文字列表記にすることでバックスラッシュのエスケープ問題を回避でき、括弧で囲むことで分割後も数字部分が結果に保持されます。
実行結果
上記のコードを実行すると、次の出力が得られます。
['Hello1', 'Hello2', 'Hello12', 'Hello17', 'Hello25', 'Hello29']
このように、sort()のkeyに関数を渡すだけで、人間にとって直感的な順序で文字列リストを並べ替えられます。ファイル名やバージョン番号など、数値を含む文字列を扱う場面で非常に役立つテクニックなので、ぜひ覚えておきましょう。
-
【保存版】PowerPointのフォーマットペインタでテキスト書式を一括コピーする方法
PowerPointでテキストを編集するとき、「フォントサイズを大きくして、色を変えて、さらに斜体にする」といったように、複数の書式設定を組み合わせて変更した経験はありませんか? せっかく整えたその書式を、ほかのテキストにも同じように適用したい場合、一つひとつの設定を手作業で繰り返すのは非常に面倒です。そんなときに便利なのがフォーマットペインタ(書式のコピー/貼り付け)です。この機能を使えば、フォントサイズ・色・スタイルなどの書式情報をまとめてコピーし、別のテキストにワンアクションで適用できます。対応バージョンこの記事で紹介する手順は、PowerPoint 2019、2016、2013、201
-
AndroidのSQLiteで文字列型の数値を正しく並べ替える方法【CAST関数活用】
Androidアプリ開発では、SQLiteが標準で組み込まれたデータベースとして広く使われています。SQLiteはオープンソースのSQLデータベースで、データを端末内のテキストファイルに保存します。リレーショナルデータベースの主要な機能をすべて備えており、JDBCやODBCのような接続設定を行うことなく、すぐにデータベースへアクセスできるのが大きな特徴です。 文字列型の数値カラムをソートする際の課題 SQLiteでは、給与などの数値をTEXT型(文字列)カラムに保存していると、単純なORDER BY句では「辞書順」でソートされてしまいます。そのため「10」が「9」より先に表示されるなど、期待