我需要遍历一个可能非常大的目录(任意大)。据我了解,常规glob.glob
函数将所有匹配文件名的列表存储在内存中,但该glob.iglob
函数使用迭代器。所以使用常规glob.glob
函数是不可能的,因为目录中可能有很多文件。
我的问题是以iglob
看似随机的顺序遍历目录。我希望它按字母顺序遍历文件。我不能一次得到所有文件名的列表,只是对它们进行排序,所以我想知道是否有一种方法可以iglob
按字母顺序遍历目录。
不,没有,没有将目录的所有内容读入内存。操作系统按目录顺序提供文件名,如果要对它们进行排序,还需要将内容全部读入内存。
您可以在匹配的文件之后对结果进行排序,前提是该集合足够小以通过调用输出来iglob()
放入内存:sorted()
iglob()
for filename in sorted(iglob(path)):
请注意,当不递归到子目录时,iglob()
已经将单个目录的所有条目加载到列表中(部分原因是fnmatch()
返回一个列表)。
从glob
模块的文档中:
该
glob
模块根据 Unix shell 使用的规则查找与指定模式匹配的所有路径名。不进行波浪号扩展,但*
,?
, 和用 表示的字符范围[]
将被正确匹配。这是通过协同使用os.listdir()
andfnmatch.fnmatch()
函数来完成的,而不是通过实际调用子 shell 来完成。
如果我们查看文档os.listdir
:
os.listdir(路径)
返回一个列表,其中包含路径给定的目录中条目的名称。 该列表是任意顺序的。它不包括特殊条目“。” 和 '..' 即使它们存在于目录中。
所以glob.glob
不按字母顺序返回文件。文档中的任何地方都没有说明。依赖这种行为是一个错误。如果你想要一个有序的序列,你必须对结果进行排序。然后你可以很容易地想象没有办法iglob
返回一个排序的结果,因为它甚至没有所有可用的结果。
如果内存真的是个问题,那么您有两种选择:
iglob
.