3

在检查效率的同时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()将返回的第三项是目录中的文件列表(其中有 600000 项)。所以,我试图找出一种方法来降低空间复杂度(至少) ,方法是以某种方式a.next()返回一个生成器对象作为元组的第三项,而不是文件名列表。

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

4

3 回答 3

1

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

如果您可以访问readdir,则可以这样做:不幸的是,这不是由 Python 直接公开的。

这个问题显示了两种方法(都有缺点)。

一种更简洁的方法是用 C 编写一个模块来公开您想要的功能。

于 2012-08-16T16:48:05.267 回答
1

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

  1. 使用 subprocess oros.system调用lsor dir(无论你碰巧在什么操作系统上)。将该命令的输出定向到一个临时文件(比如/tmp/myfiles什么。在 Python 中有一个模块可以返回一个新tmp文件)。

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

  3. 文件对象是可迭代的,并且会返回每一行,所以只要你只有文件名,你就可以了。

于 2012-08-16T17:00:10.143 回答
1

os.walk 在后台调用listdir()以检索根目录的内容,然后继续将返回的项目列表拆分为目录和非目录。

为了实现你想要的,你需要深入挖掘,不仅要实现你自己的版本,walk()还要实现一个返回 generator的替代方案listdir()。请注意,即使那样,您也无法为目录和文件提供独立的生成器,除非您对修改后的文件进行两次单独调用listdir()并即时过滤结果。

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

于 2012-08-16T17:00:59.707 回答