【Python】ファイル名などのリストを数値でソート(順番に整列)する方法:natsort

時計 2021.02.23 / 時計

【Python】ファイル名などのリストを数値でソート(順番に整列)する方法:natsort

本記事では、Pythonを使ったファイル名などのリストを数値でソート(順番に整列)する方法を解説していきます。

ファイル名などのリストを数値でソートsortする場合は、標準で使用できるsort()メソッドを使用することが多いです。
しかしこの方法では望むようにソートすることができないことがあります。

例えばos.listdir()やglob.glob()で取得したファイル名のリストが以下の場合、sort()メソッドを使用すると次のようになります。

['test1.pdf', 'test2.pdf', 'test10.pdf']

list1 = ['test1.pdf', 'test2.pdf', 'test10.pdf']
list1.sort()
print(list1)
# ['test1.pdf', 'test10.pdf', 'test2.pdf']

このようにsort()メソッドでは不自然な並びになってしまいます。

リストの文字列を自然な並びにする方法を本記事を通して学びましょう。

本記事を通して以下の知識を学べます。

学べる知識
  • sort()メソッドのソート内容
  • 自然ソートする方法
  • natsortのnatsorted()メソッドについて

sort()メソッド

数値を含んだ文字列のリストをsort()メソッドでソートすると次のようになります。

version = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
version.sort()
print(version)
# ['version-1.10', 'version-1.11', 'version-1.9', 'version-2.0']

sort()メソッドではAlphabetical sorting(アルファベットソート)をしているため、このような結果になります。

この結果を回避し、自然ソート(Natural sorting)をするためには別のモジュールを使用する必要があります。

natsortモジュール

natsortモジュールが提供するnatsorted()メソッドは、リスト内の文字列を数値でナチュラルソート(自然な整列)します。

現時点(2021年2月)で最新のバージョンは7.1.1です。

標準で入っているモジュールではないので、pipでインストールする必要があります。

pip install natsort

プログラム内で使用する際は、プログラムの先頭でインポートします。

from natsort import natsorted

natsorted()メソッドの引数に自然ソートしたいリストを指定します。
そしてnatsorted()メソッドは指定したリストを自然ソートしたリストを返します。

次にサンプルプログラムを記します。

from natsort import natsorted

version = ['version-1.9', 'version-2.0', 'version-1.11', 'version-1.10']
version = natsorted(version)
print(version)

フォルダ内のPDFファイルを結合(数値順でソート)

ここではフォルダ内のファイルを結合するプログラムをご紹介します。

プログラムの機能を以下に記します。

  • PDFファイルをすべて結合する
  • Pythonスクリプトが保存されているPDFファイルが対象
  • PDFファイル名は数値で順番が記載されているものとする
  • 結合の順番はファイル名を自然ソートした順番

ここでは自然ソートするnatsorted()メソッドを使用するため、'1','10','11'の順番にはならず、'1','2','3'…の順番で結合します。

import PyPDF2
import glob
from natsort import natsorted

pdf_writer = PyPDF2.PdfFileWriter()
# 選択されたPDFをすべて結合する
for pdf_file in natsorted(glob.glob('*.pdf')):
    pdf_reader = PyPDF2.PdfFileReader(pdf_file)
    for i in range(pdf_reader.getNumPages()):
        pdf_writer.addPage(pdf_reader.getPage(i))
pdf_name = "combine(1).pdf"
# 保存
with open(pdf_name, "wb") as f:
    pdf_writer.write(f)

このスクリプトでは、PyPDF2を使用してPDFファイルの結合を行っています。
そのためpipでPyPDF2はインストールしておく必要があります。

pip install PyPDF2

pyinstallerを使ってEXE化しておくと、Pythonをインストールしていないパソコンでもこのプログラムを走らせることができます。
使い勝手が非常に良くなるので、ぜひEXE化して使ってみてください。

まとめ

本記事「ファイル名などのリストを数値でソート(順番に整列)する方法」はいかがでしたか。

natsorted()メソッドは簡単に使用できますが、存在を知らないとわざわざ自分で自然ソートする関数を作る必要があります。

このnatsorted()のようにあまり知られていないけど使えるモジュールはたくさんあります。
本サイトでは今後も様々なモジュールを紹介していきます。