如何使用 pathlib 匹配两种模式?
How to glob two patterns with pathlib?
我想找到两种具有两种不同扩展名的文件:.jl
和 .jsonlines
。我用
from pathlib import Path
p1 = Path("/path/to/dir").joinpath().glob("*.jl")
p2 = Path("/path/to/dir").joinpath().glob("*.jsonlines")
但我希望 p1
和 p2
作为一个变量而不是两个。我应该首先合并 p1
和 p2
吗?还有其他方法可以连接 glob 的模式吗?
试试这个:
from os.path import join
from glob import glob
files = []
for ext in ('*.jl', '*.jsonlines'):
files.extend(glob(join("path/to/dir", ext)))
print(files)
受@aditi 回答的启发,我想到了这个:
from pathlib import Path
from itertools import chain
exts = ["*.jl", "*.jsonlines"]
mainpath = "/path/to/dir"
P = []
for i in exts:
p = Path(mainpath).joinpath().glob(i)
P = chain(P, p)
print(list(P))
from pathlib import Path
exts = [".jl", ".jsonlines"]
mainpath = "/path/to/dir"
# Same directory
files = [p for p in Path(mainpath).iterdir() if p.suffix in exts]
# Recursive
files = [p for p in Path(mainpath).rglob('*') if p.suffix in exts]
# 'files' will be a generator of Path objects, to unpack into strings:
list(files)
如果您可以安装软件包,请查看 wcmatch
。它可以修补 Python PathLib,这样你就可以 运行 一次性匹配多个:
from wcmatch.pathlib import Path
paths = Path('path/to/dir').glob(['*.jl', '*.jsonlines'])
根据您的应用程序,建议的解决方案可能效率低下,因为它必须多次遍历目录中的所有文件(每个文件 extension/pattern)。
在您的示例中,您只匹配一个文件夹中的扩展名,一个简单的解决方案可能是:
from pathlib import Path
folder = Path("/path/to/dir")
extensions = {".jl", ".jsonlines"}
files = [file for file in folder.iterdir() if file.suffix in extensions]
用多了可以转成函数
但是,如果您希望能够匹配 glob 模式而不是扩展名,您应该使用 match()
方法:
from pathlib import Path
folder = Path("/path/to/dir")
patterns = ("*.jl", "*.jsonlines")
files = [f for f in folder.iterdir() if any(f.match(p) for p in patterns)]
最后一个既方便又高效。您可以通过将最常见的模式放在模式列表的开头来提高效率,因为 any
是短路运算符。
keep = [".jl", ".jsonlines"]
files = [p for p in Path().rglob("*") if p.suffix in keep]
我想找到两种具有两种不同扩展名的文件:.jl
和 .jsonlines
。我用
from pathlib import Path
p1 = Path("/path/to/dir").joinpath().glob("*.jl")
p2 = Path("/path/to/dir").joinpath().glob("*.jsonlines")
但我希望 p1
和 p2
作为一个变量而不是两个。我应该首先合并 p1
和 p2
吗?还有其他方法可以连接 glob 的模式吗?
试试这个:
from os.path import join
from glob import glob
files = []
for ext in ('*.jl', '*.jsonlines'):
files.extend(glob(join("path/to/dir", ext)))
print(files)
受@aditi 回答的启发,我想到了这个:
from pathlib import Path
from itertools import chain
exts = ["*.jl", "*.jsonlines"]
mainpath = "/path/to/dir"
P = []
for i in exts:
p = Path(mainpath).joinpath().glob(i)
P = chain(P, p)
print(list(P))
from pathlib import Path
exts = [".jl", ".jsonlines"]
mainpath = "/path/to/dir"
# Same directory
files = [p for p in Path(mainpath).iterdir() if p.suffix in exts]
# Recursive
files = [p for p in Path(mainpath).rglob('*') if p.suffix in exts]
# 'files' will be a generator of Path objects, to unpack into strings:
list(files)
如果您可以安装软件包,请查看 wcmatch
。它可以修补 Python PathLib,这样你就可以 运行 一次性匹配多个:
from wcmatch.pathlib import Path
paths = Path('path/to/dir').glob(['*.jl', '*.jsonlines'])
根据您的应用程序,建议的解决方案可能效率低下,因为它必须多次遍历目录中的所有文件(每个文件 extension/pattern)。
在您的示例中,您只匹配一个文件夹中的扩展名,一个简单的解决方案可能是:
from pathlib import Path
folder = Path("/path/to/dir")
extensions = {".jl", ".jsonlines"}
files = [file for file in folder.iterdir() if file.suffix in extensions]
用多了可以转成函数
但是,如果您希望能够匹配 glob 模式而不是扩展名,您应该使用 match()
方法:
from pathlib import Path
folder = Path("/path/to/dir")
patterns = ("*.jl", "*.jsonlines")
files = [f for f in folder.iterdir() if any(f.match(p) for p in patterns)]
最后一个既方便又高效。您可以通过将最常见的模式放在模式列表的开头来提高效率,因为 any
是短路运算符。
keep = [".jl", ".jsonlines"]
files = [p for p in Path().rglob("*") if p.suffix in keep]