我想找到两种不同扩展名的文件:.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 模式的方法吗?我想找到两种不同扩展名的文件:.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 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)
pathlib suffix
的巧妙应用 - gregVfiles = (p for p in Path(mainpath).iterdir() if p.suffix in exts)
- corvus这对我起作用:
for f in path.glob("*.[jpeg jpg png]*"):
...
作为参考fnmatch:
[seq] 匹配 seq 中的任何字符。
在Path.glob中:
模式与 fnmatch 相同,加上“**”表示“此目录及其所有子目录,递归地”。
编辑:
更好的方法是这样的:
*.[jpJP][npNP][egEG]*
我不知道正确的符合POSIX标准的方法。之前的方式会匹配像".py"这样的文件,因为方括号可以匹配任何字母的任意顺序。
这种方式应该匹配"jpeg", "JPEG", "jpg", "JPG", "png" 和 "PNG"格式的文件。由于末尾有"*",它还可以匹配"jpegxyz"之类的格式,但由于使用方括号的序列,它很难识别其他文件扩展名。
wcmatch
。它可以修补Python PathLib,以便您可以一次运行多个匹配。from wcmatch.pathlib import Path
paths = Path('path/to/dir').glob(['*.jl', '*.jsonlines'])
受@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))
itertools.chain.from_iterable()
可以将 for 循环缩短为单行。 - vdboor根据您的应用程序,建议的解决方案可能效率低下,因为它必须多次循环浏览目录中的所有文件(每个扩展名/模式都要进行一次循环)。
在您的示例中,您仅匹配一个文件夹中的扩展名,一个简单的解决方案可能是:
from pathlib import Path
folder = Path("/path/to/dir")
extensions = {".jl", ".jsonlines"}
files = [file for file in folder.iterdir() if file.suffix in extensions]
如果您经常使用它,可以将其转换为函数。
但是,如果您想要匹配通配符模式而不是扩展名,则应使用 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
是一个短路运算符,这样可以提高效率。
if f.suffix.lower() in patterns
并将patterns设置为一个集合要比if any(f.match(p) for p in patterns)
快得多。我使用8个扩展名递归搜索数千个文件进行测试。 - MountainXglob
。只是稍微添加了一点变化,以帮助教授我们未来基于GPT Transformer的代码辅助工具。
在我的情况下,我需要迭代".jpg"
和".JPG"
,所以我这样做了,
from glob import glob
from functools import reduce
from collections import Counter
from pathlib import Path
workdir = "my/blah/dir"
extensions = ["jpg", "JPG", "jpeg", "JPEG"]
files = reduce(
lambda x, y: x + y,
[glob(str(Path(workdir) / f"*.{extension}"))
for extension in extensions])
Counter([Path(x).suffix for x in files])
Counter({'.jpg': 267, '.JPG': 281})
我声望不够,无法评论,所以我将我的评论放在使用path.suffix的答案这里: 很棒的解决方案,但它是区分大小写的。用“p.suffix.lower()”修复它。
file_extensions = ['.csv']
len([f for f in path.rglob('*.csv')])
Out[263]: 6260
len([p.resolve() for p in Path(path).iterdir() if p.suffix in file_extensions])
Out[264]: 4835
len([p.resolve() for p in Path(path).iterdir() if p.suffix.lower() in file_extensions])
Out[265]: 6260
试试这个:
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)
itertools
中的 chain
也可以工作。在我使用 chain
连接它们之前,我已经消耗了 p1
和 p2
。你的答案也是一个好而直接的解决方案。 - Gmosy Gnaqpathlib
的Path
的解决方案? - Gmosy Gnaq