不幸的是,这段代码运行速度比“os.walk”慢,但为什么呢?
会不会是“为”循环导致它运行缓慢?
类似于“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)
这段代码的运行速度几乎与os一样快。步行
!
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)
os。walk()
不使用操作系统。listdir()。它使用更快的操作系统。scandir()
函数,该函数为迭代器提供每个目录项的更多信息:
使用scandir()
代替listdir()
可以显著提高还需要文件类型或文件属性信息的代码的性能,因为os.如果操作系统在扫描目录时提供此信息,则DirEntry
对象会公开此信息。所有os.DirEntry
方法可以执行系统调用,但是is_dir()
和is_file()
通常只需要符号链接的系统调用;os。DirEntry.stat()
在Unix上总是需要一个系统调用,但在Windows上只需要一个符号链接。
os。walk()
code大量使用DirEntry。is_dir()
call,它与os一起使用。scandir()
比使用操作系统便宜得多。isdir()
(必须进行单独的os.stat()
调用)。
接下来,您的代码经常调用os.isdir()
。您实际上对路径中的每个文件条目调用它两次。您已经收集了y
中的所有子目录,当重新创建var
时,您不需要再次测试路径。这些额外的isdir()
调用花费了您大量的时间。
当var
为空(没有其他子目录)时,您也会递归,这会导致您首先将空列表包装到另一个列表中,然后是os。listdir()
抛出一个类型错误
异常,你的毛毯口袋妖怪会捕捉到除处理程序沉默之外的所有异常。
接下来,您应该去掉全局变量,并使用适当的变量名<代码>文件和目录
的名称要比y
和z
清晰得多。因为您创建了y
和z
全局文件,所以您将保留给定级别的所有文件和目录名,并且对于向下的每个第一个子目录,您将重新报告这些相同的文件和目录名,就好像它们是这些子目录的成员一样。只有当到达这样一个目录树的第一个叶子(没有更多的子目录)时,。clear()
执行对y
和z
的调用,导致重复文件名的结果非常混乱。
您可以研究操作系统。walk()
源代码,但如果我们将其简化为只使用自顶向下遍历而不使用错误处理,那么它将归结为:
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)
注意,没有使用全局变量;在这个算法中根本不需要任何额外的参数。只有一个操作系统。scandir()
调用每个目录,并重复使用dirs
变量递归到子目录中。
问题内容: 我有一段旧代码,用于在字符串中执行查找和替换标记。 它接收地图的和对,遍历它们并为每个对,遍历目标字符串,将查找使用,并取代它的价值。它完成对的所有工作,并最终返回。 我用以下代码替换了该代码: 并且运行了一些比较性能测试。 比较迭代时,我得到以下信息: 旧代码:1287ms 新代码:4605ms 长3倍! 然后,我尝试用3个调用替换它: 结果如下: 旧代码:1295 新代码:3524
目标 写出一个loader,实现在html文件内容前面添加个人签名、以及自动替换掉敏感词汇的功能,当对应的词汇文件修改时,页面会自动刷新。该loader需能够协作其他loader,实现链式调用。 挑战 写出一个loader,要求每个模块文件依赖于各不相同的敏感词汇json文件。 知识点 1、node module:一个loader就是一个npm包,输出一个function; 2、npm publi
对于简单的定制操作,我们或许可以通过使用layers.core.Lambda层来完成。但对于任何具有可训练权重的定制层,你应该自己来实现。 这里是一个Keras层应该具有的框架结构(1.1.3以后的版本,如果你的版本更旧请升级),要定制自己的层,你需要实现下面三个方法 build(input_shape):这是定义权重的方法,可训练的权应该在这里被加入列表`self.trainable_weigh
对于简单的定制操作,我们或许可以通过使用layers.core.Lambda层来完成。但对于任何具有可训练权重的定制层,你应该自己来实现。 这里是一个Keras2的层应该具有的框架结构(如果你的版本更旧请升级),要定制自己的层,你需要实现下面三个方法 build(input_shape):这是定义权重的方法,可训练的权应该在这里被加入列表`self.trainable_weights中。其他的属性
对于简单、无状态的自定义操作,你也许可以通过 layers.core.Lambda 层来实现。但是对于那些包含了可训练权重的自定义层,你应该自己实现这种层。 这是一个 Keras 2.0 中,Keras 层的骨架(如果你用的是旧的版本,请更新到新版)。你只需要实现三个方法即可: build(input_shape): 这是你定义权重的地方。这个方法必须设 self.built = True,可以通
前面已经提过在运行 logstash 的时候,可以通过 --pluginpath 参数来加载自己写的插件。那么,插件又该怎么写呢? 插件格式 一个标准的 logstash 输入插件格式如下: require 'logstash/namespace' require 'logstash/inputs/base' class LogStash::Inputs::MyPlugin < LogStash: