超越os.walk返回生成器对象作为第三项

时间:2012-08-16 16:35:55

标签: python os.walk

在检查os.walk的效率时,我使用字符串6,00,000 创建了Hello <number>个文件(其中number只是一个数字,表示目录中的文件编号) ,例如目录中文件的内容如下所示: -

File Name | Contents
1.txt     | Hello 1
2.txt     | Hello 2
.
.
600000.txt|Hello 600000

现在,我运行了以下代码: -

a= os.walk(os.path.join(os.getcwd(),'too_many_same_type_files')) ## Here, I am just passing the actual path where those 6,00,000 txt files are present
print a.next()

我觉得问题是a.next()占用了太多时间和内存,因为a.next()将返回的第3项是目录中的文件列表(其中有600000)项)。所以,我试图找出一种方法来减少空间复杂度(至少)通过某种方式使a.next()返回一个生成器对象作为元组的第三项,而不是列表文件名。

降低空间复杂度会是个好主意吗?

3 个答案:

答案 0 :(得分:1)

这是一个好主意,这就是底层C API的工作方式!

如果您可以访问readdir,则可以执行此操作:遗憾的是,Python并未直接公开。

This question显示了两种方法(都有缺点)。

更简洁的方法是在C中编写模块以公开您想要的功能。

答案 1 :(得分:1)

正如人们已经提到的,目录中的600,000个文件是个坏主意。最初我认为由于你如何访问文件列表而无法做到这一点,但事实证明我错了。您可以使用以下步骤来实现您的目标:

  1. 使用子流程或os.system来调用lsdir(无论您遇到什么操作系统)。将该命令的输出定向到一个临时文件(比如/tmp/myfiles或者其他东西。在Python中有一个模块可以返回一个新的tmp文件。

  2. 打开该文件以便在Python中阅读。

  3. 文件对象是可迭代的并且将返回每一行,因此只要您文件名,就可以了。

答案 2 :(得分:1)

引擎下的

os.walk calls listdir()检索根目录的内容,然后将返回的项目列表拆分为dirs和non-dirs。

要实现您想要的目标,您需要深入挖掘并实施walk()以及an alternative listdir() that returns a generator自己的版本。请注意,即使这样,您也无法为目录和文件提供独立的生成器,除非您对修改后的listdir()进行两次单独调用并动态过滤结果。

正如Sven在上面的评论中所建议的那样,解决实际问题(目录中的文件太多)可能更好,而不是过度设计解决方案。