在检查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()
返回一个生成器对象作为元组的第三项,而不是列表文件名。
降低空间复杂度会是个好主意吗?
答案 0 :(得分:1)
这是一个好主意,这就是底层C API的工作方式!
如果您可以访问readdir,则可以执行此操作:遗憾的是,Python并未直接公开。
This question显示了两种方法(都有缺点)。
更简洁的方法是在C中编写模块以公开您想要的功能。
答案 1 :(得分:1)
正如人们已经提到的,目录中的600,000个文件是个坏主意。最初我认为由于你如何访问文件列表而无法做到这一点,但事实证明我错了。您可以使用以下步骤来实现您的目标:
使用子流程或os.system
来调用ls
或dir
(无论您遇到什么操作系统)。将该命令的输出定向到一个临时文件(比如/tmp/myfiles
或者其他东西。在Python中有一个模块可以返回一个新的tmp
文件。
打开该文件以便在Python中阅读。
文件对象是可迭代的并且将返回每一行,因此只要您只文件名,就可以了。
答案 2 :(得分:1)
os.walk
calls listdir()
检索根目录的内容,然后将返回的项目列表拆分为dirs和non-dirs。
要实现您想要的目标,您需要深入挖掘并实施walk()
以及an alternative listdir()
that returns a generator自己的版本。请注意,即使这样,您也无法为目录和文件提供独立的生成器,除非您对修改后的listdir()
进行两次单独调用并动态过滤结果。
正如Sven在上面的评论中所建议的那样,解决实际问题(目录中的文件太多)可能更好,而不是过度设计解决方案。