V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
dgzting
V2EX  ›  Python

os.walk 获取路径,排除目录问题?#dirs[:] = 这种方式不适用

  •  
  •   dgzting · 2023-08-11 11:05:45 +08:00 · 1027 次点击
    这是一个创建于 500 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 、环境:目录结构如下,我想排除 D:\目录\目录 1 及其子目录,

        D:\目录
        ├─目录 1 (排除,及其子目录)
        │  ├─目录 1
        │  ├─目录 2
        │  └─目录 3
        ├─目录 2 (保留,及其子目录)
        │  ├─目录 1
        │  ├─目录 2
        │  └─目录 3
        └─目录 3 (保留,及其子目录)
            ├─目录 1
            ├─目录 2
            └─目录 3
    

    生成所有目录路径列表,想通过 if in 排除某些目录

    path = r"D:\目录"
    allDir = []
    exculdeDir=[r"D:\目录\目录 1"]
    
    for root, dirs, files in os.walk(path):
        for i in dirs:
            allDir.append(os.path.join(root, i))
    
    for dirpath in allDir:
        for exculdepath in exculdeDir:
            if exculdepath in dirpath:
                allDir.remove(dirpath)
    for i in allDir:
        print(i+" res")
    

    2 、问题: 通过这种方式,排除了 D:\目录\目录 1 ; D:\目录\目录 1\目录 1 ; D:\目录\目录 1\目录 3 ,但是不排除 D:\目录\目录 1\目录 2 ,不知道是什么原因?

    7 条回复    2023-08-11 13:39:53 +08:00
    fuge
        1
    fuge  
       2023-08-11 11:14:12 +08:00
    chatgpt 给的答案,没有经过验证。

    问题出在你在循环中修改了 allDir 列表,导致循环遍历时出现了问题。在遍历 allDir 列表的同时,你对其进行了删除操作,导致遍历的元素和列表的索引发生了混乱。

    更好的方法是,在遍历 allDir 列表时,创建一个新的列表来保存排除目录后的结果,而不是在原始列表上进行修改。以下是修正后的代码:

    python
    Copy code
    import os

    path = r"D:\目录"
    allDir = []
    exculdeDir = [r"D:\目录\目录 1"]

    for root, dirs, files in os.walk(path):
    for i in dirs:
    allDir.append(os.path.join(root, i))

    filteredDir = []

    for dirpath in allDir:
    exclude = False
    for exculdepath in exculdeDir:
    if exculdepath in dirpath:
    exclude = True
    break
    if not exclude:
    filteredDir.append(dirpath)

    for i in filteredDir:
    print(i + " res")
    这样,你就会得到正确的排除结果。在遍历 allDir 列表时,将不符合排除条件的目录路径添加到 filteredDir 列表中,然后遍历输出 filteredDir 列表,得到正确的排除结果。
    NoOneNoBody
        2
    NoOneNoBody  
       2023-08-11 11:17:06 +08:00
    1.不要在循环中改变循环的目标,问题可能出在这里
    2.建议用 os.scandir ,可以一边递归一边排除,不用跑两遍循环
    3.如果搜索完再集中处理,有 pandas 模块的话,用 panadas.series.str 相关函数向量化处理更快,当然 allDir 数量少就不必了
    deplivesb
        3
    deplivesb  
       2023-08-11 11:19:50 +08:00
    列表不要一边便利一边删除
    nuk
        4
    nuk  
       2023-08-11 12:10:46 +08:00
    for dirpath in allDir[:]:
    zhzy
        5
    zhzy  
       2023-08-11 13:18:56 +08:00
    glob 了解一下
    dgzting
        6
    dgzting  
    OP
       2023-08-11 13:38:05 +08:00
    感谢各位支持,已解决问题,是遍历中同时删除导致
    dgzting
        7
    dgzting  
    OP
       2023-08-11 13:39:53 +08:00
    @NoOneNoBody 感谢,已解决问题,同时感谢提供一些其他思路
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1374 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 17:18 · PVG 01:18 · LAX 09:18 · JFK 12:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.