首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带正则表达式的Python自顶向下

带正则表达式的Python自顶向下
EN

Stack Overflow用户
提问于 2015-06-24 00:42:08
回答 3查看 1.8K关注 0票数 2

我不明白为什么以下内容只适用于topdown=False,而在设置为True时不返回任何内容?

我想使用topdown=True的原因是因为遍历目录需要很长时间。我相信自上而下会增加编制名单所需的时间。

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-24 01:28:15

在您的代码中,您正在查找要遍历的匹配名称(dmp\d{8}),而在向全局列表中添加匹配名称时,您应该查找要遍历的不匹配目录。

我修改了您的代码,这是可行的:

代码语言:javascript
复制
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”

票数 1
EN

Stack Overflow用户

发布于 2015-06-24 01:52:41

这是因为根目录与regex不匹配,所以在第一次迭代之后,dirs被设置为空。

如果您想要找到所有匹配该模式的子目录,您应该:

  1. 使用topdown = False,或
  2. 不要修剪目录
票数 1
EN

Stack Overflow用户

发布于 2015-06-24 01:53:05

问题是在遍历时正在修改dirs的内容。当使用topdown=True时,这将影响接下来要遍历的目录。

看看这段代码,它向您展示了正在发生的事情:

代码语言:javascript
复制
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,上面的输出将产生如下结果:

代码语言:javascript
复制
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,我们得到了这样的信息:

代码语言:javascript
复制
Walked down ./, dirs=['Temp']
After filtering dirs is now: []

因为您要从dirs中删除所有子目录,所以您告诉os.walk您不想进一步遍历任何子目录,因此迭代就停止了。在使用topdown=False时,dirs的修改值不用于确定下一步要遍历的内容,因此它可以工作。

若要修复它,请将dirs[:] =替换为dirs =

代码语言:javascript
复制
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)

这使我们:

代码语言:javascript
复制
D12345678

更新:

如果您绝对确信某个目录将不包含您感兴趣的任何子目录,则可以在进一步遍历之前将它们从dirs中删除。例如,如果您知道“./Temp/MyDirs2 2”将永远不包含任何感兴趣的子目录,则当我们到达以加快速度时,您可以空出dirs

代码语言:javascript
复制
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)

除此之外,您不可能知道哪些目录不需要遍历,因为要知道它们是否包含有趣的子目录,就必须遍历它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31015780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档