不幸的是,这段代码的运行速度比"os.walk“慢,但是为什么呢?
会不会是"for“循环导致它运行缓慢?
“代码”,类似于'os.walk': ( "os.walk“函数做它所做的事情)
注:我写是为了提高我自己!
import os, time
from os.path import *
x = ""
y = []
z = []
var = 0
def walk(xew):
global top, var, x,y,z
if not var: var = [xew]
for i in var:
try:
for ii in os.listdir(i):
y.append(ii) if isdir(i+os.sep+ii) else z.append(ii)
x = top = i
var = [top+os.sep+i for i in os.listdir(top) if isdir(top+os.sep+i)]
except:
continue
yield x,y,z
yield from walk(var)
var.clear();y.clear();z.clear(),例如
它在2秒内结束:
for x,y,z in walk(path):
print(x)在0.5秒内:
for x,y,z in os.walk(path):
print(x)发布于 2019-01-28 12:45:46
os.walk()不使用os.listdir()。它使用速度快得多的 function,它为迭代器提供了每个目录条目更多的信息:
使用
scandir()而不是listdir()可以显著提高还需要文件类型或文件属性信息的代码的性能,因为如果操作系统在扫描目录时提供这些信息,则os.DirEntry对象会公开该信息。所有os.DirEntry方法都可以执行系统调用,但是is_dir()和is_file()通常只需要对符号链接进行系统调用;os.DirEntry.stat()总是需要在Unix上进行系统调用,但在Windows上只需要一个符号链接。
os.walk()代码大量使用了DirEntry.is_dir()调用,使用os.scandir()比使用os.isdir() (必须单独进行os.stat()调用)要便宜得多。
接下来,您的代码调用os.isdir()太频繁了。您实际上是对路径中的每个文件项调用了两次。您已经收集了y中的所有子目录,在重新创建var时不需要再次测试路径。这些额外的isdir()电话花费了你很多时间。
您还可以在var为空时(不再有子目录)进行递归,这将导致您首先将空列表包装在另一个列表中,然后os.listdir()抛出一个TypeError异常,除了处理程序的静默之外,所有这些都会引发TypeError异常。
接下来,您应该去掉全局变量,并使用适当的变量名。files和dirs的名字比y和z要清晰得多。因为您创建了y和z全局文件,所以您将保留给定级别的所有文件和目录名称,并且对于每个第一个子目录,然后重新报告相同的文件和目录名称,就好像它们是这些子目录的成员一样。只有当到达这样一个目录树的第一个叶(没有更多的子目录)时,才会执行对y和z的z调用,从而导致重复文件名带来非常混乱的结果。
您可以学习 source code,但是如果我们将其简化为只使用自顶向下的遍历而不使用错误处理,则可以归结为:
def walk(top):
dirs = []
nondirs = []
with os.scandir(top) as scandir_it:
for entry in scandir_it:
if entry.is_dir():
dirs.append(entry.name)
else:
nondirs.append(entry.name)
yield top, dirs, nondirs
for dirname in dirs:
new_path = os.path.join(top, dirname)
yield from walk(new_path)请注意,没有使用全局变量;在此算法中根本不需要任何变量。每个目录只有一个os.scandir()调用,dirs变量被重新用于递归到子目录。
发布于 2019-01-28 22:22:09
这段代码的工作速度几乎和os.walk一样快!
import os, time
from os.path import *
def walk(top):
x = top;y=[];z=[]
try:
for i in os.listdir(top):
y.append(i) if isdir(top+os.sep+i) else z.append(i)
except: pass
else:
yield x,y,z
for q in y: yield from walk(top+os.sep+q)https://stackoverflow.com/questions/54402246
复制相似问题