遍历文件结构Python的最有效方法

遍历文件结构Python的最有效方法,python,optimization,directory,subdirectory,Python,Optimization,Directory,Subdirectory,使用os.walk是否是递归搜索文件夹并返回以.tnt结尾的所有文件的最省时方法 for root, dirs, files in os.walk('C:\\data'): print "Now in root %s" %root for f in files: if f.endswith('.tnt'): 是的,使用os.walk确实是最好的方法。正如大家所说,os.walk几乎肯定是最好的方法 如果您确实存在性能问题,并且分析表明这是由os.walk(和/或

使用os.walk是否是递归搜索文件夹并返回以.tnt结尾的所有文件的最省时方法

for root, dirs, files in os.walk('C:\\data'):
    print "Now in root %s" %root
    for f in files:
        if f.endswith('.tnt'):

是的,使用
os.walk
确实是最好的方法。

正如大家所说,
os.walk
几乎肯定是最好的方法

如果您确实存在性能问题,并且分析表明这是由os.walk(和/或使用.endswith迭代结果)引起的,那么最好的答案可能是跳出Python。将上述所有代码替换为:

for f in sys.argv[1:]:
现在需要一些外部工具来收集路径并运行脚本。(理想情况下,将尽可能多的路径批处理到每个脚本执行中。)

如果您可以依靠Windows桌面搜索为驱动器编制索引,则它只需执行快速数据库操作即可查找特定路径下具有特定扩展名的所有文件。我不知道如何编写一个批处理文件来运行该查询并将结果作为参数列表传递给Python脚本(或一个PowerShell文件,该文件运行该查询并将结果传递给IronPython,而无需将其序列化为参数列表),但这是值得研究的

如果您不能依赖平台的桌面搜索索引,在任何POSIX平台上,使用以下一行shell脚本肯定是最快、最简单的:

find /my/path -name '*.tnt' -exec myscript.py {} +
不幸的是,您不是在POSIX平台上,而是在Windows上,Windows没有
find
工具,而这正是在这里完成所有繁重工作的工具

有find到本机窗口的端口,但是您必须找出命令行的复杂性,才能正确引用所有内容并格式化路径等等,这样您就可以编写一行批处理文件了。或者,您可以安装cygwin并使用与POSIX系统完全相同的shell脚本。或者你可以找到一个更适合你需要的Windows-y工具

这可能比速度慢,因为Windows并不是设计用来以尽可能少的开销执行许多小进程的,而且我相信它在命令行上的限制比linux或OS X等平台更小,因此您可能会花更多的时间等待解释器启动和退出,而不是节省时间。你必须测试才能看到。事实上,您可能希望测试本机和cygwin版本(在后一种情况下,使用本机和cygwin Python)

实际上,您不必将
find
调用移动到批处理/shell脚本中;这可能是最简单的答案,但也有其他答案,比如在Python中使用
subprocess
调用
find
。这可能会解决由于多次启动解释器而导致的性能问题

获得适当的并行度也有助于将脚本的每次调用剥离到后台,而不必等待它们完成。(我相信在Windows上,shell与此无关;相反,有一个名为“run”的工具可以启动与shell分离的进程。但我不记得细节。)


如果这些都不起作用,您可能需要编写一个定制的C扩展,以尽可能快地完成Win32或.NET的工作(这也意味着您必须进行研究以找出这是什么…)因此,您可以从Python中调用它。

我想您可以从中生成一个列表理解,它可能会稍微快一点,也可能会稍微少一点键入。不要忘记聪明人曾经说过的话:。使用
os.walk
是一个好方法。这是最好的方式吗?我不确定。但我同意这一点。为什么列表理解会更快?这将涉及实际生成一个列表,而不是使用这个
os.walk
generator…@nneonneo:好的,重点是——一个生成器表达式。这不是过早的优化。我只是希望有一种方法可以随时了解os.scandir()?@denfromufa:
os.scandir()
是在Python 3.5中添加的(在发布此答案很久之后)
os.walk()
被重新配置为使用
os.scandir()
,因此
os.walk()
仍然是递归扫描目录的最有效方法。关键是对于
Python2.7
您可以安装作者提供的pypi包
scandir
!它将我的网络目录扫描速度从18秒提高到6秒!啊,当然,但是你没有提到你安装了一个外部软件包!然后我会复制并使用它,而不是2.7
os.walk()
函数。@denfromufa:更好!