python - 避免递归树行走中的基本路径
问题描述
我知道如何d:\temp
使用各种方法递归列出所有文件/文件夹,请参阅如何使用 glob() 递归查找文件?.
但通常我想避免d:\temp\
在结果中使用前缀,而是使用到此基础的相对路径。
这可以通过以下方式完成:
-
import os, glob for f in glob.glob('d:\\temp\\**\\*', recursive=True): print(os.path.relpath(f, 'd:\\temp'))
f.lstrip('d:\\temp\\')
删除此前缀的同上-
import pathlib root = pathlib.Path("d:\\temp") print([p.relative_to(root) for p in root.glob("**/*")])
这 3 个解决方案有效。但实际上,如果您阅读 的源代码glob.py
,它确实会累积/连接路径的所有部分。所以上面的解决方案是......“删除之前刚刚添加的东西”!它有效,但不是很优雅。Idem for pathlib
with relative_to
which 删除前缀。
问题:如何修改接下来的几行以不包含d:\temp
在输出中(不删除之前连接的内容!)?
import os
def listpath(path):
for f in os.scandir(path):
f2 = os.path.join(path, f)
if os.path.isdir(f):
yield f2
yield from listpath(f2)
else:
yield f2
for f in listpath('d:\\temp'):
print(f)
#d:\temp\New folder
#d:\temp\New folder\New Text Document - Copy.txt
#d:\temp\New folder\New Text Document.txt
#d:\temp\New Text Document - Copy.txt
#d:\temp\New Text Document.txt
解决方案
您可以执行以下示例中所示的操作。基本上,我们递归地返回将它们连接在一起的路径部分,但我们不加入初始根。
import os
def listpath(root, parent=''):
scan = os.path.join(root, parent)
for f in os.scandir(scan):
f2 = os.path.join(parent, f.name)
yield f2
if f.is_dir():
yield from listpath(root, f2)
for f in listpath('d:\\temp'):
print(f)
在尚未发布的 Python 3.10 中,将有一个新root_dir
选项允许您毫无问题地使用内置 glob 执行此操作:
import glob
glob.glob('**/*', root_dir='d:\\temp', recursive=True)
您还可以使用 3rd 方库,例如已经实现此行为的wcmatch库(我是该库的作者)。但在这种简单的情况下,您的listpath
方法可能就足够了。
推荐阅读
- python - 简化歌曲和艺术家姓名
- python - 在两个单词之间插入连字符以在 Python 中的 URL 中使用
- group-by - 将列数据分组并存储在 Mysql 中的单独命名列中
- spring-boot - spring-boot-maven-plugin build-info.properties
- google-developers-console - 您的付款资料目前已暂停 - Google 控制台
- r - 如何在传单地图中为形状文件的部分着色
- python - Dask 数据框:`set_index` 可以将单个索引放入多个分区吗?
- javascript - Javascript 生成的输入被忽略
- javascript - React Native:使用有效负载导航的操作未由任何导航器处理
- azure - 如何在 Azure 网关应用程序中传递密钥