在POSIX也没有在Windows中,你不能让所有的数据在一个操作系统调用。至少,对于POSIX,将有三个每个目录(opendir
,readdir
,close
),加上每个目录项一(stat
)。
我相信接下来的操作会导致比您发布的操作系统更少的操作。是的,os.walk()
调用是懒惰的;也就是说,整个树是不在在从walk()
回内存,但是调用next()
过程中,而读零碎。
因此,我的版本将只读取1阶子孙的目录,并且将stat
仅限于直系子孙。你的版本也会为所有的曾孙辈做这项工作,就像你的目录结构一样。
root='.'
grandChildren = []
for kid in next(os.walk('.'))[1]:
x = next(os.walk(os.path.join('.', kid)))
for grandKid in x[1]: # (or x[1]+x[2] if you care about regular files)
grandChildren.append(os.path.join(x[0], grandKid))
或者作为一个列表的理解,而不是一个for循环:
import os
root='.'
grandChildren = [
os.path.join(kid, grandKid)
for kid in next(os.walk(root))[1]
for grandKid in next(os.walk(os.path.join(root, kid)))[1]]
最后,分解出os.walk
s转换功能:
def read_subdirs(dir='.'):
import os
return (os.path.join(dir,x) for x in next(os.walk(dir))[1])
root='.'
grandChildren = [
grandKid
for kid in read_subdirs(root)
for grandKid in read_subdirs(kid)]
从测试中,我们可以看到,我的版本呼叫
stat
的次数要比只有曾孙的人少很多。
在我的主目录,例如,我跑我的代码(/tmp/a.py
)和你们(/tmp/b.py
)与root
设置为'.'
在每种情况下:
$ strace -e stat python /tmp/a.py 2>&1 > /dev/null | egrep -c stat
1245
$ strace -e stat python /tmp/b.py 2>&1 > /dev/null | egrep -c stat
36049
你看了'unipath'模块? – 2013-03-06 20:16:51
[This answer](http://stackoverflow.com/a/4117594/8747)可能会揭示出来。 – 2013-03-06 20:18:43
你只对孙子或者第二世代和后代的所有后代感兴趣吗?也就是说,将'root/a/b/c/d'包含在搜索中还是排除在外? – 2013-03-06 20:21:01