我很困惑为什么以下仅适用于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)
答案 0 :(得分:1)
在你的代码中,你正在寻找匹配的名称([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
返回:
['根/ temp1目录/ myfiles的/ d12345678&#39 ;,
'根/ temp1目录/ myfiles的/ m11111111&#39 ;,
'根/ TEMP2 / mydirs / moredirs / m22222222&#39 ;,
'根/ TEMP2 / mydirs / moredirs / p00000001']
答案 1 :(得分:1)
这是因为您的根目录与正则表达式不匹配,因此在第一次迭代后,dirs设置为空。
如果你想要的是找到与模式匹配的所有子目录,你应该:
答案 2 :(得分:1)
问题是您在遍历时修改了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 / D12345678 (我在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”永远不会包含任何感兴趣的子目录,那么当我们到达那里加速时,您可以清空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)
除此之外,您无法知道哪些目录不需要遍历,因为要知道它们是否包含有趣的子目录,您必须遍历它们。