避免递归树遍历中的基本路径
Avoid the base path in a recursive tree walking
我知道如何使用各种方法递归列出 d:\temp
的所有 files/folders,请参阅 How to use glob() to find files recursively?。
但通常我想避免在结果中使用 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
的源代码,它会执行 accumulate/join all 路径部分。所以上面的解决方案是......“删除之前刚刚添加的东西”!它有效,但不是很优雅。 pathlib
与 relative_to
相同,删除了前缀。
问题:如何修改接下来的几行,使输出中没有 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
您可以执行以下示例中所示的操作。基本上,我们递归地 return 将路径部分连接在一起,但我们不连接初始根。
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)
您还可以使用第 3 方库,例如 wcmatch 库,它已经实现了此行为(我是其作者)。但在这种简单的情况下,您的 listpath
方法可能就足够了。
我知道如何使用各种方法递归列出 d:\temp
的所有 files/folders,请参阅 How to use glob() to find files recursively?。
但通常我想避免在结果中使用 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
的源代码,它会执行 accumulate/join all 路径部分。所以上面的解决方案是......“删除之前刚刚添加的东西”!它有效,但不是很优雅。 pathlib
与 relative_to
相同,删除了前缀。
问题:如何修改接下来的几行,使输出中没有 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
您可以执行以下示例中所示的操作。基本上,我们递归地 return 将路径部分连接在一起,但我们不连接初始根。
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)
您还可以使用第 3 方库,例如 wcmatch 库,它已经实现了此行为(我是其作者)。但在这种简单的情况下,您的 listpath
方法可能就足够了。