我不明白为什么以下内容只适用于topdown=False,而在设置为True时不返回任何内容?
我想使用topdown=True的原因是因为遍历目录需要很长时间。我相信自上而下会增加编制名单所需的时间。
for root, dirs, files in os.walk(mypath, topdown=False): #Why doesn't this work with True?
dirs[:] = [d for d in dirs if re.match('[DMP]\\d{8}$', d)]
for dir in dirs:
print(dir)发布于 2015-06-24 01:28:15
在您的代码中,您正在查找要遍历的匹配名称(dmp\d{8}),而在向全局列表中添加匹配名称时,您应该查找要遍历的不匹配目录。
我修改了您的代码,这是可行的:
import os
import re
all_dirs = []
for root, dirs, files in os.walk("root", topdown=True):
subset = []
for d in dirs:
if not re.match('[dmp]\d{8}$', d):
# step inside
subset.append(d)
else:
# add to list
all_dirs.append(os.path.join(root, d))
dirs[:] = subset
print all_dirs这将返回:
‘’root/temp1 1/myfiles/d12345678‘, ‘'root/temp1/myfiles/m11111111', ‘’root/temp2 2/mydirs/moredirs/m22222222‘, “根/温度2/米迪尔斯/莫尔迪尔斯/p00000001”
发布于 2015-06-24 01:52:41
这是因为根目录与regex不匹配,所以在第一次迭代之后,dirs被设置为空。
如果您想要找到所有匹配该模式的子目录,您应该:
发布于 2015-06-24 01:53:05
问题是在遍历时正在修改dirs的内容。当使用topdown=True时,这将影响接下来要遍历的目录。
看看这段代码,它向您展示了正在发生的事情:
import os, re
for root, dirs, files in os.walk("./", topdown=False):
print("Walked down {}, dirs={}".format(root, dirs))
dirs[:] = [d for d in dirs if re.match('[DMP]\\d{8}$', d)]
print("After filtering dirs is now: " + str(dirs))
for dir in dirs:
print(dir)我只有一个目录可以遍历-Temp/MyFiles/D 12345678(我在Linux上)。使用topdown=False,上面的输出将产生如下结果:
Walked down ./Temp/MyFiles/D12345678, dirs=[]
After filtering dirs is now: []
Walked down ./Temp/MyFiles, dirs=['D12345678']
After filtering dirs is now: ['D12345678']
D12345678
Walked down ./Temp, dirs=['MyFiles']
After filtering dirs is now: []
Walked down ./, dirs=['Temp']
After filtering dirs is now: []但是通过topdown=True,我们得到了这样的信息:
Walked down ./, dirs=['Temp']
After filtering dirs is now: []因为您要从dirs中删除所有子目录,所以您告诉os.walk您不想进一步遍历任何子目录,因此迭代就停止了。在使用topdown=False时,dirs的修改值不用于确定下一步要遍历的内容,因此它可以工作。
若要修复它,请将dirs[:] =替换为dirs =
import os, re
for root, dirs, files in os.walk("./", topdown=True):
dirs = [d for d in dirs if re.match('[DMP]\\d{8}$', d)]
for dir in dirs:
print(dir)这使我们:
D12345678更新:
如果您绝对确信某个目录将不包含您感兴趣的任何子目录,则可以在进一步遍历之前将它们从dirs中删除。例如,如果您知道“./Temp/MyDirs2 2”将永远不包含任何感兴趣的子目录,则当我们到达以加快速度时,您可以空出dirs:
import os, re
uninteresting_roots = { "./Temp/MyDirs2" }
for root, dirs, files in os.walk("./", topdown=True):
if root in uninteresting_roots:
# Empty dirs and end this iteration
del dirs[:]
continue
dirs = [d for d in dirs if re.match('[DMP]\\d{8}$', d)]
for dir in dirs:
print(dir)除此之外,您不可能知道哪些目录不需要遍历,因为要知道它们是否包含有趣的子目录,就必须遍历它们。
https://stackoverflow.com/questions/31015780
复制相似问题