以低于最耗时的方式使用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'):
答案 0 :(得分:5)
是的,使用os.walk
确实是最好的方法。
答案 1 :(得分:2)
正如大家所说,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上,它没有附带find
工具,这就是在这里做所有繁重工作的事情。
找到本机Windows的端口,但你必须弄清楚命令行的复杂性,以便正确引用所有内容并格式化路径等等,这样你就可以编写单行批处理文件了。或者,您可以安装cygwin并使用您在POSIX系统上使用的完全相同的shell脚本。或者你可以找到一个更符合你需要的Windows-y工具。
这可能比较慢而不是更快 - Windows不是设计用尽可能少的开销执行大量的小进程,我相信它比Linux或OS X这样的平台对命令行有更小的限制,所以你可能会花更多的时间等待翻译开始和退出而不是你保存。你必须测试才能看到。实际上,您可能希望测试native和cygwin版本(在后一种情况下使用native和cygwin Python)。
您实际上没有将find
调用移动到批处理/ shell脚本中;它可能是最简单的答案,但还有其他答案,例如使用subprocess
从Python中调用find
。这可能会解决因启动解释器太多次而导致的性能问题。
获得适当的并行度也可能有助于将脚本的每次调用分离到后台,而不是等待它们完成。 (我相信在Windows上,shell不参与其中;相反,有一个名为“run”的工具可以启动与shell分离的进程。但我不记得详细信息。)
如果这一切都没有成功,你可能必须编写一个自定义的C扩展,它可以做最快的Win32或.NET(这也意味着你必须进行研究以找出它是什么......)所以你可以从Python中调用它。