Pythonのglob.globはどのように並べられますか?


199

次のPythonコードを記述しました。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os, glob

path = '/home/my/path'
for infile in glob.glob( os.path.join(path, '*.png') ):
    print infile

今私はこれを手に入れます:

/home/my/path/output0352.png
/home/my/path/output0005.png
/home/my/path/output0137.png
/home/my/path/output0202.png
/home/my/path/output0023.png
/home/my/path/output0048.png
/home/my/path/output0069.png
/home/my/path/output0246.png
/home/my/path/output0071.png
/home/my/path/output0402.png
/home/my/path/output0230.png
/home/my/path/output0182.png
/home/my/path/output0121.png
/home/my/path/output0104.png
/home/my/path/output0219.png
/home/my/path/output0226.png
/home/my/path/output0215.png
/home/my/path/output0266.png
/home/my/path/output0347.png
/home/my/path/output0295.png
/home/my/path/output0131.png
/home/my/path/output0208.png
/home/my/path/output0194.png

それはどのように注文されますか?

それはあなたが私のls -l出力を得るのを助けるかもしれません:

-rw-r--r-- 1 moose moose 627669 2011-07-17 17:26 output0005.png
-rw-r--r-- 1 moose moose 596417 2011-07-17 17:26 output0023.png
-rw-r--r-- 1 moose moose 543639 2011-07-17 17:26 output0048.png
-rw-r--r-- 1 moose moose 535384 2011-07-17 17:27 output0069.png
-rw-r--r-- 1 moose moose 543216 2011-07-17 17:27 output0071.png
-rw-r--r-- 1 moose moose 561776 2011-07-17 17:27 output0104.png
-rw-r--r-- 1 moose moose 501865 2011-07-17 17:27 output0121.png
-rw-r--r-- 1 moose moose 547144 2011-07-17 17:27 output0131.png
-rw-r--r-- 1 moose moose 530596 2011-07-17 17:27 output0137.png
-rw-r--r-- 1 moose moose 532567 2011-07-17 17:27 output0182.png
-rw-r--r-- 1 moose moose 553562 2011-07-17 17:27 output0194.png
-rw-r--r-- 1 moose moose 574065 2011-07-17 17:27 output0202.png
-rw-r--r-- 1 moose moose 552197 2011-07-17 17:27 output0208.png
-rw-r--r-- 1 moose moose 559809 2011-07-17 17:27 output0215.png
-rw-r--r-- 1 moose moose 549046 2011-07-17 17:27 output0219.png
-rw-r--r-- 1 moose moose 566661 2011-07-17 17:27 output0226.png
-rw-r--r-- 1 moose moose 561678 2011-07-17 17:27 output0246.png
-rw-r--r-- 1 moose moose 525550 2011-07-17 17:27 output0266.png
-rw-r--r-- 1 moose moose 565715 2011-07-17 17:27 output0295.png
-rw-r--r-- 1 moose moose 568381 2011-07-17 17:28 output0347.png
-rw-r--r-- 1 moose moose 532768 2011-07-17 17:28 output0352.png
-rw-r--r-- 1 moose moose 535818 2011-07-17 17:28 output0402.png

ファイル名やサイズの順ではありません。

その他のリンク:globls


2
最後の答えは、lsコマンド自体がファイルを名前でソートすることです。'ls -U'は、「ディレクトリ順」のファイルの順不同リストを提供します。
ブライアンピーターソン

2
Windowsではソートされていたので、常にそうだと思いました。Ubuntuでは、デバッグにコストがかかりました。自己注意-APIを読んでください!:0)
Yuri Feldman

動作は次の場合と同じos.listdirです。* nix OSは、アルファベット順ではないファイル順でファイルを返します。(驚いたことに、残念なことに!)これはドキュメントで明示されています:「リストは任意の順序です」。
ジョエル

回答:


112

それはおそらくまったくソートされておらず、ファイルシステムにエントリが現れる順序、つまりを使用しls -Uたときに得られる順序を使用します。(少なくとも私のマシンでは、これはリストのglob一致と同じ順序を生成します)。


1
はい、特別な努力をしない限り、オペレーティングシステムが提供するエントリを表示するだけです。Unixの「find」コマンドと同じで、基礎となるファイルシステムが使用するデータ構造からのエントリをダンプします。ファイルが作成順に表示されているように見える場合でも、その順序については想定しないでください。
ラウル・サリナス- Monteagudo

421

順序は任意ですが、自分で並べ替えることができます

名前でソートしたい場合:

sorted(glob.glob('*.png'))

修正時間でソート:

import os
sorted(glob.glob('*.png'), key=os.path.getmtime)

サイズで並べ替え:

import os
sorted(glob.glob('*.png'), key=os.path.getsize)


1
名前が単なる整数で拡張子のないファイルがあるので、以下を使用しますfiles = glob.glob('teksty/*')。ナムによる注文は許可されますか?
andilabs 2014年

3
@mgalgsいいえ、それは私が本当に質問するつもりだった質問ではありませんでした。私が知りたかったことは、Xionによって答えられました。
Martin Thoma

そして、それを作成日でソートし、作成時間でソートするのはどうでしょうか。それは私が最初に最新のファイルをリストしているからです。古いファイルから最新のファイルへのリストを取得するにはどうすればよいですか?ありがとうございました!
joaquindev 2018

1
getmtimeとのgetSizeは比較的高価であることに注意してください-たくさんのファイルのためにこれをやっては時間がかかる場合があります...
drevicko

53

glob.globあなたのソースコードをチェックすることによって、それが内部的にを呼び出すことがわかりos.listdirます。

http://docs.python.org/library/os.html?highlight=os.listdir#os.listdir

キーセンテンス:os.listdir(path)pathで指定されたディレクトリ内のエントリの名前を含むリストを返します。リストは任意の順序です。特別なエントリ「。」は含まれません。および「..」は、それらがディレクトリに存在する場合でも使用されます。

任意の順序。:)


14

glob.glob()はos.listdir()のラッパーであるため、基になるOSがデータの配信を担当します。一般に、ここでの順序を仮定することはできません。基本的な前提は順序付けなしです。並べ替えが必要な場合:アプリケーションレベルで並べ替えます。


13

順序は任意ですが、並べ替えにはいくつかの方法があります。それらの1つは次のとおりです。

#First, get the files:
import glob
import re
files =glob.glob1(img_folder,'*'+output_image_format)
# if you want sort files according to the digits included in the filename, you can do as following:
files = sorted(files, key=lambda x:float(re.findall("(\d+)",x)[0]))

既存の回答と比較して、あなたの回答は何に貢献していますか?
Martin Thoma

2
@MartinThomaファイルに存在する整数にゼロが埋め込まれていない場合、ファイル名を並べ替えずに並べ替えると問題があります。並べ替えは1000から始まり、最大の整数が何であれ、最小の整数から始めます。数値をゼロで埋める場合、ファイルでソートを呼び出すだけで完全にソートされます。したがって、このソリューションは、単独でソートしても機能しない場合の問題を解決すると思います。
Will.Evo

1
@ Will.Evo使用してみてnatsortくださいfrom natsort import natsorted; files = natsorted(files)
Martin Thoma

あなたの答えは役に立ちました!
Vineet

12

同様の問題があり、globファイル名のリストを任意の順序で返していましたが、ファイル名で示されている番号順にファイル名を確認したいと思っていました。これは私がそれを達成した方法です:

私のファイルはglob次のようなものによって返されました:

myList = ["c:\tmp\x\123.csv", "c:\tmp\x\44.csv", "c:\tmp\x\101.csv", "c:\tmp\x\102.csv", "c:\tmp\x\12.csv"]

リストを所定の位置に並べ替え、これを行うために関数を作成しました。

def sortKeyFunc(s):
    return int(os.path.basename(s)[:-4])

この関数は、ファイル名の数値部分を返し、整数に変換します。次に、リストのsortメソッドを呼び出しました。

myList.sort(key=sortKeyFunc)

これはそのようなリストを返しました:

["c:\tmp\x\12.csv", "c:\tmp\x\44.csv", "c:\tmp\x\101.csv", "c:\tmp\x\102.csv", "c:\tmp\x\123.csv"]

os.path.splitext(os.path.basename(s))[0]代わりに使う方がエレガントだと思いますos.path.basename(s)[:-4]ので、関数定義はそうなります。 def sortKeyFunc(s): return int(os.path.splitext(os.path.basename(s))[0])
ePandit

1

過去にシステムでglob.globが何を実行したのか疑問に思っていて、sorted呼び出しを追加できない場合、順序はMac HFS +ファイルシステムで一貫し、他のUnixシステムではトラバーサル順序になります。したがって、ファイルが追加、削除、名前変更、削除、移動などされた場合に発生する可能性のある、基礎となるファイルシステムが再編成されない限り、それはおそらく確定的です。


macOSのAPFSはどうですか?
ボリス

0

@Johan La Rooyのソリューションから、使用sorted(glob.glob('*.png'))して画像を並べ替えることはできませんが、出力リストは名前順に並べられていません。

しかし、sorted(glob.glob('*.png'), key=os.path.getmtime)作品は完全に動作します。

ここでは、名前による並べ替えが機能しないので、少し混乱しています。

この素晴らしい質問を投稿してくれた@Martin Thomaと、役立つ解決策を@Johan La Rooyに感謝します。


-1

このコードを試してください:

sorted(glob.glob( os.path.join(path, '*.png') ),key=lambda x:float(re.findall("([0-9]+?)\.png",x)[0]))

-3
'''my file name is 
"0_male_0.wav", "0_male_2.wav"... "0_male_30.wav"... 
"1_male_0.wav", "1_male_2.wav"... "1_male_30.wav"... 
"8_male_0.wav", "8_male_2.wav"... "8_male_30.wav"

when I wav.read(files) I want to read them in a sorted torder, i.e., "0_male_0.wav"
"0_male_1.wav"
"0_male_2.wav" ...
"0_male_30.wav"
"1_male_0.wav"
"1_male_1.wav"
"1_male_2.wav" ...
"1_male_30.wav"
so this is how I did it.

Just take all files start with "0_*" as an example. Others you can just put it in a loop
'''

import scipy.io.wavfile as wav
import glob 
from os.path import isfile, join

#get all the file names in file_names. THe order is totally messed up
file_names = [f for f in listdir(audio_folder_dir) if isfile(join(audio_folder_dir, f)) and '.wav' in f] 
#find files that belongs to "0_*" group
filegroup0 = glob.glob(audio_folder_dir+'/0_*')
#now you get sorted files in group '0_*' by the last number in the filename
filegroup0 = sorted(filegroup0, key=getKey)

def getKey(filename):
    file_text_name = os.path.splitext(os.path.basename(filename))  #you get the file's text name without extension
    file_last_num = os.path.basename(file_text_name[0]).split('_')  #you get three elements, the last one is the number. You want to sort it by this number
    return int(file_last_num[2])

それは私が私の特定のケースをした方法です。お役に立てれば幸いです。


1
質問に合わせて回答を変更する必要があります。
CodenameLambda

1
問題は並べ替えについてではありません。並べ替えの方法を知っています(当時は知っていました)。問題は、デフォルトの順序についてです。
Martin Thoma

1
このコードスニペットをお寄せいただきありがとうございます。すぐに役立つ情報が得られる場合があります。適切な説明は、なぜこれが問題の優れた解決策であるを示すことにより、教育的価値を大幅に向上させ、同様の、しかし同一ではない質問を持つ将来の読者にとってより有用になります。回答を編集して説明を追加し、適用される制限と前提を示してください。
Toby Speight 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.