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)
尤里·费尔德曼

行为与以下内容相同os.listdir:* nix OS以非字母顺序返回文件,并且(很遗憾让我感到羞耻!)在文档中明确指出:“列表按任意顺序排列”。
乔尔

Answers:


112

它可能根本没有排序,并使用条目在文件系统中出现的顺序,即使用时所获得的顺序ls -U。(至少在我的机器上,这产生与列表glob匹配相同的顺序)。


1
是的,除非进行特殊工作,否则它将仅显示操作系统提供的条目。与Unix中的“查找”命令相同,它只是按照条目来自基础文件系统所使用的数据结构的顺序转储条目。即使您看到文件似乎按照创建顺序出现,也不应对它的顺序做任何假设。
劳尔·萨利纳斯-蒙塔古多

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/*')。nam会下订单吗?
andilabs 2014年

3
@mgalgs不,那不是我真正想问的问题。锡安回答了我想知道的事情。
马丁·托马

并按创建日期但根据创建时间对其进行排序呢?因为它首先列出了我的最新文件。如何获取旧文件到最新文件的列表?谢谢!
joaquindev

1
请注意,getmtime和getsize相对昂贵-对于许多文件执行此操作可能需要一段时间
。.– drevicko


14

glob.glob()是os.listdir()的包装,因此底层操作系统负责传递数据。一般而言:您不能在此假设订购。基本假设是:顺序。如果需要某种排序:在应用程序级别上排序。


13

顺序是任意的,但是有几种方法可以对它们进行排序。其中之一如下:

#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]))

与现有答案相比,您的答案有什么作用?
马丁·托马

2
@MartinThoma我有一个问题,如果文件中存在的整数不是零填充,则不对文件名进行排序。排序从1000开始,直到最大的整数,然后从最小的整数重新开始。如果我将数字零填充,则只需调用对文件排序就可以对它们进行完美排序。因此,我认为这种解决方案可以解决无法单独排序的问题。
Will.Evo

@ Will.Evo尝试使用natsortfrom natsort import natsorted; files = natsorted(files)
马丁·托马

您的回答有所帮助!
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
您应该更改答案以适合该问题。
代号

1
问题不在于排序。我知道(那时我也知道)如何排序。问题是关于默认顺序。
Martin Thoma

1
感谢您提供此代码段,它可能会立即提供帮助。通过说明为什么这是一个解决问题的好方法,正确的解释将大大提高其教育价值,并且对将来有相似但不相同的问题的读者来说更有用。请编辑您的答案以添加说明,并指出适用的限制和假设。
Toby Speight
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.