在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