glob.glob() 的返回值是按照什么顺序排序的?

329

我编写了以下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

它是按照哪种方式排序的?

澄清一下:我不想进行排序 - 我知道sorted。我想知道它默认以哪种顺序出现。

这里是我的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" 给出了一个按目录顺序未排序的文件列表。 - Brian Peterson
5
在Windows上,它被排序了,所以我就认为它总是这样的...现在在Ubuntu上,这让我付出了调试的代价。自己注意一下 - 读API! :0) - Yuri Feldman
1
行为与 os.listdir 相同:*nix 操作系统以相当非字母顺序返回文件,而(惭愧的是我感到惊讶!)这在文档中是明确说明的:“列表是任意顺序”。 - Joël
12个回答

615

顺序是任意的,但你可以自己进行排序。

如果你想按名称排序:

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

按修改时间排序:

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

按大小排序:

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

等等。


2
我有一些文件,它们的名称只是整数,没有扩展名,所以我使用:files = glob.glob('teksty/*')。文件按名称排序会被授予吗? - andilabs
5
不,那不是我真正想问的问题。我想知道的是由Xion回答了。 - Martin Thoma
那么按创建日期排序,但根据创建时间呢?因为它先列出了最新的文件。我怎样才能得到从旧到最新的文件列表呢?谢谢! - joaquindev
3
请注意,getmtime和getsize的成本较高 - 对大量文件执行此操作可能需要一些时间。 - drevicko
太好了!它也可以与pathlib.Path一起使用,例如pathlib.Path('.').glob('*') - imbr

158

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


6
除非它做出特殊的努力,否则它将只显示操作系统提供的条目。与Unix中的“find”命令相同,它只是按照基础文件系统使用的数据结构提供的顺序转储条目。您不应该对其排序做出任何假设,即使您看到文件似乎按创建顺序出现。 - Raúl Salinas-Monteagudo

77
通过检查 glob.glob 的源代码,您可以看到它在内部调用了 os.listdir,这里有描述:http://docs.python.org/library/os.html?highlight=os.listdir#os.listdir 关键句子: os.listdir(path='.') 返回一个包含给定路径中目录条目名称的列表。该列表是任意排序的。即使在目录中存在,它也不包括特殊条目 '.''..'任意排序

25

顺序是任意的,但有几种排序方法。其中之一如下:

#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 我在使用sorted函数时遇到了问题,如果文件名中的整数没有进行零填充,则无法对其进行排序。排序从1000开始,一直到最高整数,然后从最小整数重新开始。如果我对数字进行零填充,只需调用文件上的sorted函数即可完美地对它们进行排序。因此,我认为这个解决方案可以解决sorted函数无法正常工作的问题。 - Will.Evo
7
尝试使用 natsortfrom natsort import natsorted; files = natsorted(files) - Martin Thoma
你的回答很有帮助! - Vineet

18

我曾经遇到过类似的问题,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"]

2
我认为使用 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

16

glob.glob()是os.listdir()的封装,因此底层操作系统负责提供数据。一般来说:没有排序规则,不能假设排序顺序。如果需要排序:请在应用程序级别上进行排序。


10

至少在Python3中,您也可以这样做:

import os, re, glob

path = '/home/my/path'
files = glob.glob(os.path.join(path, '*.png'))
files.sort(key=lambda x:[int(c) if c.isdigit() else c for c in re.split(r'(\d+)', x)])
for infile in files:
    print(infile)

这应该按字典顺序排序您输入的字符串数组(例如,在排序时要考虑字符串中的数字)。

1
这正是我所需要的。 注意:此处将文件排序为“image1”、“image2”……、“image9”、“image10”、“image11”…… - Shailesh Appukuttan

9

根据@Johan La Rooy的解决方案,使用sorted(glob.glob('*.png'))对图像进行排序对我不起作用,输出列表仍未按名称排序。

然而,sorted(glob.glob('*.png'), key=os.path.getmtime) 运行得非常完美。

我有点糊涂了,如何在这里按它们的名称排序就行了。

感谢@Martin Thoma提出这个很棒的问题以及@Johan La Rooy提供的有帮助的解决方案。


2
我认为按字母顺序更适合这个解决方案,因为Linux上的文件日期可能会有所不同。因此,如果在文件名中使用排序号码(具有相同数量的数字),也可以使用字母顺序:sorted(glob.glob('*.png'), key=os.path.basename) - s3n0
由于某些原因,key=os.path.basename对我不起作用,但os.path.getmtime可以。我自己觉得这很奇怪,但只是想分享一下我所面临的问题。 - Suprateem Banerjee

5

我使用内置的sorted来解决这个问题:

from pathlib import Path

p = Path('/home/my/path')
sorted(list(p.glob('**/*.png')))

2
如果您想知道 glob.glob 在过去在您的系统上做了什么,但无法添加 sorted 调用,则在 Mac HFS+ 文件系统 上排序将保持一致,并且在其他 Unix 系统上将是 遍历顺序。因此,它很可能是确定性的,除非底层文件系统被重新组织,这可能会发生如果添加、删除、重命名、删除、移动等文件。

macOS 上的 APFS 怎么样? - user3064538

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接