glob.iglob结果按名称排序



我需要遍历一个潜在的非常大的目录(任意大)。据我所知,常规的glob.glob函数在内存中存储所有匹配文件名的列表,但glob.iglob函数使用迭代器。因此,使用常规的glob.glob函数是不可能的,因为目录中可能有很多文件。

我的问题是iglob以看似随机的顺序遍历目录。我希望它按字母顺序遍历文件。我不能一次得到所有文件名的列表,只对它们进行排序,所以我想知道是否有办法让iglob按字母顺序遍历目录。

不,没有,除非将目录的所有内容读取到内存中。操作系统按目录顺序提供文件名,如果要对其进行排序,还需要将内容完全读取到内存中。

您可以在iglob()匹配的文件之后对结果进行排序,前提是该集足够小,可以通过在iglob()输出上调用sorted()来放入内存:

for filename in sorted(iglob(path)):

请注意,当不递归到子目录时,iglob()已经将单个目录的所有条目加载到列表中(部分原因是fnmatch()返回列表)。

来自glob模块的文档:

glob模块查找与指定模式匹配的所有路径名根据Unix shell使用的规则。没有波浪形扩展完成,但*?和用[]表示的字符范围将为正确匹配这是通过使用os.listdir()fnmatch.fnmatch()协同工作,而不是通过实际调用潜艇外壳。

如果我们查看os.listdir:的文档

os.listdir(路径)

返回一个列表,其中包含由路径给定的目录中的条目的名称。列表按任意顺序排列。它不包括特殊条目"。"one_answers".."即使他们出现在目录

因此glob.glob不会按字母顺序返回文件。文件中没有说明。依赖这种行为是个错误。如果您想要一个有序的序列,必须对结果进行排序。然后,您可以很容易地想象,没有办法让iglob返回排序的结果,因为它甚至没有所有可用的结果。

如果内存真的是个问题,那么你有两个选择:

  1. 放弃"适用订单"要求,只使用iglob
  2. 使用某种"桶排序"对数据进行排序,将大部分数据保存在磁盘上,并将其分块加载到RAM中(这些技术在《计算机编程艺术》第3册中有解释)。这种方法会使你的程序更慢,而且可能更难写。但是,如果你真的不能将所有文件名保存在RAM中,那么你最终将不得不将它们保存在磁盘上

最新更新