【问题标题】:How are glob.glob()'s return values ordered?glob.glob() 的返回值是如何排序的?
【发布时间】:2011-10-10 01:21:26
【问题描述】:

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

【问题讨论】:

  • 最终的答案似乎是ls 命令本身按名称对文件进行排序。 'ls -U' 以“目录顺序”给出文件的无序列表。
  • 在 Windows 上它是排序的,所以我只是假设它总是这样......现在在 Ubuntu 上它花费了我调试。注意自我 - 阅读 api! :0)
  • 行为与os.listdir 相同:*nix OS 以完全非字母顺序返回文件,并且(让我感到惊讶!)this is explicit in the documentation:“列表在任意顺序”。

标签: python glob


【解决方案1】:

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

如果要按名称排序:

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

按修改时间排序:

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

按大小排序:

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

等等

【讨论】:

  • 我有文件,其中名称只是整数,没有扩展名,所以我使用:files = glob.glob('teksty/*')。 nam的订单会被授予吗?
  • @mgalgs 不,这不是我真正要问的问题。我想知道的,Xion回答了。
  • 那么按创建日期但按创建时间排序呢?因为它首先列出了我最新的文件。如何获取从旧文件到最新文件的列表?谢谢!
  • 请注意,getmtime 和 getsize 相对昂贵 - 对很多文件执行此操作可能需要一段时间..
【解决方案2】:

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

【讨论】:

  • 是的,除非它特别努力,否则它只会按照操作系统提供的方式显示条目。与 Unix 中的命令“find”相同,它只是按照条目来自底层文件系统使用的数据结构的顺序转储条目。即使您会看到文件似乎按创建顺序显示,您也不应该对其顺序做出任何假设。
【解决方案3】:

通过查看glob.glob 的源代码,您会发现它在内部调用了os.listdir,如下所述:

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

关键句:

os.listdir(path='.')
返回一个列表,其中包含路径给定的目录中条目的名称。该列表是任意顺序的。它不包括特殊条目'.''..',即使它们存在于目录中。

任意顺序.

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

    • 与现有答案相比,您的答案有何贡献?
    • @MartinThoma 如果文件中存在的整数不是零填充,我有一个问题,即 sorted 不排序文件名。排序从 1000 开始,上升到最高整数,然后从最小整数重新开始。如果我对数字进行零填充,只需对文件调用 sorted 即可完美地对它们进行排序。所以我认为这个解决方案解决了单独排序不起作用时的问题。
    • @Will.Evo 尝试使用natsortfrom natsort import natsorted; files = natsorted(files)
    • 你的回答有帮助!
    【解决方案5】:

    glob.glob() 是 os.listdir() 的包装器,因此底层操作系统负责传递数据。一般来说:您不能对此处的排序做出假设。基本假设是:no 排序。如果您需要一些排序:在应用程序级别排序。

    【讨论】:

      【解决方案6】:

      我遇到了类似的问题,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])
      

      这个函数返回文件名的数字部分并转换为整数。然后我就这样调用了列表的排序方法:

      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])
      【解决方案7】:

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

      但是,sorted(glob.glob('*.png'), key=os.path.getmtime) 可以完美运行。

      我有点困惑,怎么按他们的名字排序在这里不起作用。

      感谢@Martin Thoma 发布这个好问题,感谢@Johan La Rooy 提供有用的解决方案。

      【讨论】:

      • 我认为字母顺序更适合这个解决方案,因为文件日期在 Linux 上的变化可能不同。所以如果文件名中使用顺序号(位数相同),也可以使用字母顺序:sorted(glob.glob('*.png'), key=os.path.basename)
      • 出于某种原因 key=os.path.basename 对我不起作用,但 os.path.getmtime 可以。我自己觉得这很奇怪,但只是想分享我所面临的。
      【解决方案8】:

      至少在 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)
      

      这应该按字典顺序对您的输入字符串数组进行排序(例如,在排序时尊重字符串中的数字)。

      【讨论】:

      • 这正是我所需要的。注意:这会将文件排序为“image1”、“image2”、....、“image9”、“image10”、“image11”、...
      【解决方案9】:

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

      【讨论】:

      • macOS 上的 APFS 怎么样?
      【解决方案10】:

      我使用了内置的 sorted 所以解决了这个问题:

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

      【讨论】:

        【解决方案11】:

        请试试这个代码:

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

        【讨论】:

        • 这是什么魔法?
        【解决方案12】:
        '''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])
        

        我就是这样处理我的特殊情况的。希望对您有所帮助。

        【讨论】:

        • 你应该改变你的答案以适应问题。
        • 问题不在于排序。我知道(我当时就知道)如何排序。问题是关于默认顺序。
        • 感谢您提供此代码 sn-p,它可能会提供一些即时帮助。一个正确的解释would greatly improve 其教育价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有类似但不相同的问题的读者更有用。请edit您的答案添加解释,并说明适用的限制和假设。
        猜你喜欢
        • 2016-10-03
        • 1970-01-01
        • 1970-01-01
        • 2019-08-16
        • 2012-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多