🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Q&A

解決済

3回答

10145閲覧

Python3 ファイルを順番通りに読み込みたい

selva604

総合スコア14

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

1グッド

2クリップ

投稿2018/09/30 09:58

前提・実現したいこと

現在、python3系でファイル読み込みをしています.順番に読み込みたいのですがうまくいきません。

発生している問題・エラーメッセージ

../scene/res3\0.jpg ../scene/res3\1.jpg ../scene/res3\10.jpg ../scene/res3\11.jpg ../scene/res3\12.jpg ../scene/res3\13.jpg ../scene/res3\14.jpg ../scene/res3\15.jpg ../scene/res3\16.jpg ../scene/res3\2.jpg ../scene/res3\3.jpg ../scene/res3\4.jpg ../scene/res3\5.jpg ../scene/res3\6.jpg ../scene/res3\7.jpg ../scene/res3\8.jpg ../scene/res3\9.jpg

###理想の出力
以下の通りに出力したいです。

../scene/res3\0.jpg ../scene/res3\1.jpg ../scene/res3\2.jpg ../scene/res3\3.jpg ../scene/res3\4.jpg ../scene/res3\5.jpg ../scene/res3\6.jpg ../scene/res3\7.jpg ../scene/res3\8.jpg ../scene/res3\9.jpg ../scene/res3\10.jpg ../scene/res3\11.jpg ../scene/res3\12.jpg ../scene/res3\13.jpg ../scene/res3\14.jpg ../scene/res3\15.jpg ../scene/res3\16.jpg

該当のソースコード

files = glob.glob("../scene/res3/*.jpg") for index,path in enumerate(files): print(path)

試したこと

sort()してみましたが、理想の出力とはいきませんでした。

kankan0👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jun68ykt

2018/09/30 10:12

ご質問には、../scene/res3\0.jpg とありますが、 ファイル名がこのように、 res3 の直後はバックスラッシュなのでしょうか?
selva604

2018/09/30 10:58

いえ、ファイル名は"0.jpg","1.jpg"のようにバックスラッシュはなく、"res"フォルダの直下にこれらファイルがあります。
guest

回答3

0

ベストアンサー

sorted() では辞書順ソートなので、1, 10, 2, 20, ... のようになります。

質問にあるように 1, 2, 10, 20, ... のようなソートを自然順ソートといいます。
Python の標準ライブラリでは用意されていないので、自作するか、外部ライブラリを使います。

以下は natsort というライブラリを使うサンプルコードを示します。
インストールは以下のコマンドでできます。

pip install natsort

サンプルコード

python

1import random 2from natsort import natsorted 3 4paths = [r'../scene/res3\0.jpg', 5 r'../scene/res3\1.jpg', 6 r'../scene/res3\2.jpg', 7 r'../scene/res3\3.jpg', 8 r'../scene/res3\10.jpg', 9 r'../scene/res3\11.jpg', 10 r'../scene/res3\12.jpg'] 11# 順番をシャッフルする。 12random.shuffle(paths) 13 14# 辞書順ソート 15print('dict order sort') 16for path in sorted(paths): 17 print(path) 18print('natural sort') 19# 自然順ソート 20for path in natsorted(paths): 21 print(path)
dict order sort ../scene/res3\0.jpg ../scene/res3\1.jpg ../scene/res3\10.jpg ../scene/res3\11.jpg ../scene/res3\12.jpg ../scene/res3\2.jpg ../scene/res3\3.jpg natural sort ../scene/res3\0.jpg ../scene/res3\1.jpg ../scene/res3\2.jpg ../scene/res3\3.jpg ../scene/res3\10.jpg ../scene/res3\11.jpg ../scene/res3\12.jpg

投稿2018/09/30 10:12

編集2018/09/30 10:13
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

selva604

2018/09/30 11:29

理想の出力となりました。ありがとうございました。
guest

0

tiitoi さんのご回答のnatsortedを使うのがスマートですね。

もし、natsorted を使わないで頑張るとすれば、ファイル名の数字を取り出して数値に変換し、これをソートキーにするように自分で書く必要があります。そのようにしたものが以下です。

python

1import sys 2import random 3import re 4 5# ファイル一覧 6files = ''' 7../scene/res3/abc.jpg 8../scene/res3/0.jpg 9../scene/res3/1.jpg 10../scene/res3/10.jpg 11../scene/res3/11.jpg 12../scene/res3/12.jpg 13../scene/res3/13.jpg 14../scene/res3/14.jpg 15../scene/res3/15.jpg 16../scene/res3/16.jpg 17../scene/res3/2.jpg 18../scene/res3/3.jpg 19../scene/res3/4.jpg 20../scene/res3/5.jpg 21../scene/res3/6.jpg 22../scene/res3/7.jpg 23../scene/res3/8.jpg 24../scene/res3/9.jpg 25'''.split() 26 27random.shuffle(files) # ランダムにシャッフルします。 28 29# ファイル名の数字をキャプチャする正規表現 30path_pattern = re.compile(r'/(\d+).jpg$') 31 32 33# 与えられたパスからファイル名の数字部分を数値に変換して返す関数 34def file_number(path): 35 m = path_pattern.search(path) 36 if m: 37 return int(m.group(1)) 38 else: 39 return sys.maxsize # パターンに合わない場合、大きな数を返す。(ソートで末尾に寄せるため) 40 41 42sorted_files = sorted(files, key=lambda path: file_number(path)) 43 44print(sorted_files) # ソート結果を表示します。 45

上記を実行すると以下が表示されます。

text

1['../scene/res3/0.jpg', '../scene/res3/1.jpg', '../scene/res3/2.jpg', '../scene/res3/3.jpg', '../scene/res3/4.jpg', '../scene/res3/5.jpg', '../scene/res3/6.jpg', '../scene/res3/7.jpg', '../scene/res3/8.jpg', '../scene/res3/9.jpg', '../scene/res3/10.jpg', '../scene/res3/11.jpg', '../scene/res3/12.jpg', '../scene/res3/13.jpg', '../scene/res3/14.jpg', '../scene/res3/15.jpg', '../scene/res3/16.jpg', '../scene/res3/abc.jpg'] 2

投稿2018/09/30 11:38

編集2018/09/30 11:40
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

selva604

2018/09/30 11:55

コメントありがとうございます。natsortedを使わないとなかなか難しいですね。。。勉強になります。ありがとうございました。
jun68ykt

2018/09/30 12:09

どういたしまして。 もう一つお節介させて頂きますと、selva604 さんがふだんお使いのシェルで、コマンド sort に -V オプションが使えるならば、 ls ../scene/res3 | sort -V でも望む結果を得られるかもしれません。 -V は version sort を指定するもので、どんなソートをしてくれるかは、以下をざっと追うとだいたいつかめると思います。 https://stackoverflow.com/questions/4493205/unix-sort-of-version-numbers
guest

0

数字部分の桁に合わせて0埋めした2次元リストをソートしてループすれば可能です。
もっと楽なのはファイル名の命名規則を0埋めしてしまうことですが。

Python3

1src = ['0','1','2','10','11','12'] 2print(src) 3src.sort() 4print(src) 5 6lst = [['%02d' % int(s),s] for s in (src) ] 7lst.sort() 8print(lst) 9 10for file in lst: 11 print(file[1])
['0', '1', '2', '10', '11', '12'] ['0', '1', '10', '11', '12', '2'] [['00', '0'], ['01', '1'], ['02', '2'], ['10', '10'], ['11', '11'], ['12', '12']] 0 1 2 10 11 12

投稿2018/09/30 11:11

opyon

総合スコア1009

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

selva604

2018/09/30 11:43

コメントありがとうございます。 実行してみましたが以下のようなエラーがでました。invalid literal for int() with base 10: '../scene/res3\0.jpg'
opyon

2018/09/30 11:48

本質的な部分のみのコードですのでご自分で組み込んで頂ければと。 コード見れば分かると思ったのですが説明不足ですみません。 ファイル名から数字のみを取得する部分は省いてます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問