在 Python 中检查目录是否为空的最快方法是什么
What is the fastest way to check whether a directory is empty in Python
我在 windows 机器上工作,想检查网络路径上的目录是否为空。
首先想到的是调用 os.listdir()
并查看它的长度是否为 0。
即
def dir_empty(dir_path):
return len(os.listdir(dir_path)) == 0
因为这是一个网络路径,我的网络连接并不总是很好,而且一个文件夹可能包含数千个文件,所以这是一个非常慢的解决方案。还有更好的吗?
目前我找到的最快的解决方案:
def dir_empty(dir_path):
return not any((True for _ in os.scandir(dir_path)))
或者,如以下评论中所建议:
def dir_empty(dir_path):
return not next(os.scandir(dir_path), None)
在慢速网络上,我正在处理这个问题需要几秒钟而不是几分钟(os.listdir() 版本需要几分钟)。这似乎更快,因为 any 语句只计算第一个 True 语句。
listdir
给出了一个列表。 scandir
给出一个迭代器,它的性能可能更高。
def dir_empty(dir_path):
try:
next(os.scandir(dir_path))
return False
except StopIteration:
return True
从 Python 3.4 开始,您可以使用 pathlib.iterdir()
这将生成目录内容的路径对象:
>>> from pathlib import Path
>>>
>>> def dir_empty(dir_path):
... path = Path(dir_path)
... has_next = next(path.iterdir(), None)
... if has_next is None:
... return True
... return False
使用os.stat
:
is_empty = os.stat(dir_path).st_size == 0
使用 Python 的 pathlib:
from pathlib import Path
is_empty = Path(dir_path).stat().st_size == 0
由于 OP 询问的是最快的方法,我认为一旦找到第一个文件就使用 os.scandir
和 returns 应该是最快的。 os.scandir
returns 一个迭代器。我们应该避免为了检查它是否为空而创建整个列表。
测试目录包含约10万个文件:
from pathlib import Path
import os
path = 'jav/av'
len(os.listdir(path))
>>> 101204
然后开始我们的测试:
def check_empty_by_scandir(path):
with os.scandir(path) as it:
return not any(it)
def check_empty_by_listdir(path):
return not os.listdir(path)
def check_empty_by_pathlib(path):
return not any(Path(path).iterdir())
%timeit check_empty_by_scandir(path)
>>> 179 µs ± 878 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit check_empty_by_listdir(path)
>>> 28 ms ± 185 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit check_empty_by_pathlib(path)
>>> 27.6 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
正如我们所见,check_empty_by_listdir
和 check_empty_by_pathlib
比 check_empty_by_scandir
慢了大约 155 倍。 os.listdir() 和 Path.iterdir() 的结果相同,因为 Path.iterdir() 在后台使用 os.listdir(),在内存中创建整个列表。
此外,正如人们指出的那样,阅读 os.stat 不是一个选项,returns 4096 在 linux.
中的空目录上
在 Windows OS 上有 PathIsDirectoryEmptyA。我们可以用它来检查文件夹是否为空。
def is_dir_empty(path:str)->bool:
import ctypes
shlwapi = ctypes.OleDLL('shlwapi')
return shlwapi.PathIsDirectoryEmptyA(path.encode('utf-8'))
我在 windows 机器上工作,想检查网络路径上的目录是否为空。
首先想到的是调用 os.listdir()
并查看它的长度是否为 0。
即
def dir_empty(dir_path):
return len(os.listdir(dir_path)) == 0
因为这是一个网络路径,我的网络连接并不总是很好,而且一个文件夹可能包含数千个文件,所以这是一个非常慢的解决方案。还有更好的吗?
目前我找到的最快的解决方案:
def dir_empty(dir_path):
return not any((True for _ in os.scandir(dir_path)))
或者,如以下评论中所建议:
def dir_empty(dir_path):
return not next(os.scandir(dir_path), None)
在慢速网络上,我正在处理这个问题需要几秒钟而不是几分钟(os.listdir() 版本需要几分钟)。这似乎更快,因为 any 语句只计算第一个 True 语句。
listdir
给出了一个列表。 scandir
给出一个迭代器,它的性能可能更高。
def dir_empty(dir_path):
try:
next(os.scandir(dir_path))
return False
except StopIteration:
return True
从 Python 3.4 开始,您可以使用 pathlib.iterdir()
这将生成目录内容的路径对象:
>>> from pathlib import Path
>>>
>>> def dir_empty(dir_path):
... path = Path(dir_path)
... has_next = next(path.iterdir(), None)
... if has_next is None:
... return True
... return False
使用os.stat
:
is_empty = os.stat(dir_path).st_size == 0
使用 Python 的 pathlib:
from pathlib import Path
is_empty = Path(dir_path).stat().st_size == 0
由于 OP 询问的是最快的方法,我认为一旦找到第一个文件就使用 os.scandir
和 returns 应该是最快的。 os.scandir
returns 一个迭代器。我们应该避免为了检查它是否为空而创建整个列表。
测试目录包含约10万个文件:
from pathlib import Path
import os
path = 'jav/av'
len(os.listdir(path))
>>> 101204
然后开始我们的测试:
def check_empty_by_scandir(path):
with os.scandir(path) as it:
return not any(it)
def check_empty_by_listdir(path):
return not os.listdir(path)
def check_empty_by_pathlib(path):
return not any(Path(path).iterdir())
%timeit check_empty_by_scandir(path)
>>> 179 µs ± 878 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit check_empty_by_listdir(path)
>>> 28 ms ± 185 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit check_empty_by_pathlib(path)
>>> 27.6 ms ± 140 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
正如我们所见,check_empty_by_listdir
和 check_empty_by_pathlib
比 check_empty_by_scandir
慢了大约 155 倍。 os.listdir() 和 Path.iterdir() 的结果相同,因为 Path.iterdir() 在后台使用 os.listdir(),在内存中创建整个列表。
此外,正如人们指出的那样,阅读 os.stat 不是一个选项,returns 4096 在 linux.
中的空目录上在 Windows OS 上有 PathIsDirectoryEmptyA。我们可以用它来检查文件夹是否为空。
def is_dir_empty(path:str)->bool:
import ctypes
shlwapi = ctypes.OleDLL('shlwapi')
return shlwapi.PathIsDirectoryEmptyA(path.encode('utf-8'))