- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
不幸的是,这段代码比“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)
最佳答案
os.walk()
不使用 os.listdir()
。它使用更快的 os.scandir()
function ,它为每个目录条目提供了一个包含更多信息的迭代器:
Using
scandir()
instead oflistdir()
can significantly increase the performance of code that also needs file type or file attribute information, becauseos.DirEntry
objects expose this information if the operating system provides it when scanning a directory. Allos.DirEntry
methods may perform a system call, butis_dir()
andis_file()
usually only require a system call for symbolic links;os.DirEntry.stat()
always requires a system call on Unix but only requires one for symbolic links on Windows.
os.walk()
代码大量使用了 DirEntry.is_dir()
调用,它与 os.scandir()
比使用 os.isdir()
(必须进行单独的 os.stat()
调用)便宜得多。
接下来,您的代码过于频繁地调用 os.isdir()
。您实际上是在为路径中的每个文件条目调用它两次。您已经收集了y
中的所有子目录,重新创建var
时无需再次测试路径。这些额外的 isdir()
调用会花费您很多时间。
当 var
为空(没有进一步的子目录)时,您也会递归,导致您首先将空列表包装在另一个列表中,然后是 os.listdir ()
抛出一个 TypeError
异常,你的毯子 Pokemon-catch-em-all 除了处理程序沉默。
接下来,您应该摆脱全局变量,并使用适当的变量名。 files
和 dirs
的名称要比 y
和 z
清晰得多。因为您制作了 y
和 z
全局变量,所以您保留了给定级别的所有文件和目录名称,并且对于向下的每个第一个子目录,您然后重新报告这些相同的文件和目录名称,就好像它们是这些子目录的成员一样。仅当到达此类目录树的第一个叶子(没有进一步的子目录)时,才会对 y
和 z
调用 .clear()
被执行,导致带有重复文件名的非常困惑的结果。
可以研究os.walk()
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
变量被重新用于递归到子目录。
关于python - 自己编写的 os.walk-alike 比 os.walk 本身慢得多 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54402246/
是否有任何库允许我使用与在 BeanUtils 中使用的相同的已知符号来提取 POJO 参数,但可以轻松替换字符串中的占位符? 我知道可以自己动手,使用 BeanUtils 本身或其他具有类似功能的库
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我有相同数据(公司)的 2 个信息源,我可以通过唯一 ID(契约(Contract)号)将它们连接在一起。第二个不同来源的存在是由于这两个来源是手动独立更新的。所以我在 2 个表中有一个 ID 和一个
我目前正在开发一个应用程序,它的用户界面很像 Twitter for Mac(像 iOS 一样插入/推出 View )。 有人为桌面 Cocoa 实现了 UIViewController 吗?这将为我
我有一个关于在 Ubuntu 上使用 Arduino Uno-R3 进行编码的一般性问题。我想买一个ebay。我确实看到了很多类似的(不是 arduino 品牌的),但价格更低。我打算通过将其插入 u
我正在尝试编写一个Mysql查询,将数据库中所有相同的条目分组为一个。我有一个具有不同颜色名称的数据库,数据库中的条目就像 Contract Color OG-46374 I.Kh
在重构 PostgreSql 函数时(更具体地说:在搜索“未使用”函数时),有一个函数可用于在函数定义中搜索特定字符串会很方便。 有谁知道这是否是最好的方法(尝试“grep”搜索函数定义)或者是否有可
目前,我有一个像 facebook 的新提要这样的 View ,其中按时间顺序列出用户的帖子。现在在右侧,我想放置字母滚动条,当用户滚动到任何字符时,他们可以搜索名称以该字符开头的用户的帖子,但这可能
这是我的 python 代码: from numpy import * from copy import * def Grid(s, p): return random.binomial(1,
我陷入了一个令人惊讶的问题。 我在我的应用程序中加载了一个文本文件,我有一些逻辑来比较具有 µ 的值。 而且我意识到即使文本相同,比较值也是错误的。 Console.WriteLine("μ".Eq
我陷入了一个令人惊讶的问题。 我在我的应用程序中加载了一个文本文件,我有一些逻辑来比较具有 µ 的值。 而且我意识到即使文本相同,比较值也是错误的。 Console.WriteLine("μ".Eq
考虑以下(glytchfull)字符串: raybradbury la foire defiténébres 在调用 Azure 拼写检查器 API 后,我可以替换该字符串。建议如下: "raybrad
我构建了一个基于事件的 java html 解析器:Lagarto .现在我正在研究 DOM 构建器,它使用解析器创建 DOM 树。同时,我开发了 CSS3 选择器节点过滤器 java 库,可以很好地
当我点击菜单中的“home”按钮时,我想要一个反向移动的页面转换(data-transition="slide")。 是否存在类似 data-transition="slideBACK"的内容? 最佳
我正在使用 golang 通过以下方法通过 exim 发送电子邮件 const sendmail = "/usr/sbin/exim" func submitMail(m *gomail.Messag
我有两个包含许多字段的 data.tables。 我想连接这两个表,添加一些计算字段并附加第一个、第二个或两个表中的所有其他字段(类似于 SQL 的 select a+b AS sum, DT1.*,
不幸的是,这段代码比“os.walk”运行得慢,但为什么呢? 会不会是“for”循环导致运行缓慢? “像‘os.walk’一样工作的代码:(“os.walk”函数做它做的事) 注意:我写作是为了提升自
我需要改变表的所有主键 UPDATE TODO SET id = id + 1 但我做不到(Demo 来自 Ahmad Al-Mutawa 的回答)描述了原因。主键不能这样改。 我也不能根据这是 sq
我是一名优秀的程序员,十分优秀!