How to get all grandchildren of a directory in python with only one OS call
我试图在python中获取某个目录的所有孙子。出于性能方面的考虑,我不想一直在循环中调用操作系统函数(它是一个网络文件系统)。这就是我目前的情况。有更简单的方法吗?
1 2 3 4 5 6 7 | dirTree = os.walk(root) children = [os.path.join(root, x) for x in dirTree.next()[1]] grandChildren = [] for root, dirs, files in dirTree: if root in children: for dir in dirs: grandChildren.append(os.path.join(root, dir)) |
编辑:我不清楚我打给os.walk的电话是不是很懒。我的意思是,我打电话后,整棵树都应该在记忆中,但我不确定。
如果我能正确回答你的问题。
您可以使用glob获取文件或目录,方法是提供通配符标记。例如,要在列表中获取"/home/"中的所有dir,可以这样做。
1 | glob.glob('/home/*/*/') |
或者尽你所能了解所有的文件
1 | glob.glob('/home/*/*') |
在POSIX或Windows中,不能在一次操作系统调用中获取所有数据。对于posix,每个目录至少有三个(
我相信接下来的操作系统调用会比你发布的少。是的,
因此,我的版本将只在一阶后代目录中读取,而
1 2 3 4 5 6 | 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循环:
1 2 3 4 5 6 | 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]] |
最后,将
1 2 3 4 5 6 7 8 9 | 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)] |
通过测试,我们可以看到,如果有曾孙,我的版本调用
例如,在我的主目录中,我运行我的代码(
1 2 3 4 | $ 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 |