递归创建目录:搜索递归

时间:2021-02-15 16:10:45

标签: python

我有一个目录名称列表:

dirnames = ["foo/bar", "foo/bar/mydir", "bar/mydir", "bar"]

我想(递归地)创建所有目录。只需要递归地创建最深的目录就足够了。在这种情况下,只需:

os.makedirs("foo/bar/mydir")
os.makedirs("bar/mydir")

问题:如何将 dirnames 减少到只有最深的目录?

2 个答案:

答案 0 :(得分:1)

dirnames = ["foo/bar", "foo/bar/mydir", "bar/mydir", "bar","foo/bar/dir2"]
from itertools import groupby
import heapq
d=[sorted(list(g)) for (k,g) in groupby(sorted(dirnames), key= lambda x: x.split('/')[0])]
[max(elem) for elem in d]

或者如果你需要2的深度

[heapq.nlargest(2, elem) for elem in d]

在父目录上使用 groupby。即 foobar。如果我们使用 max 我们只会得到 foo/bar/mydir 因为它的长度大于 foo/bar/dir2 。 为了避免这种情况,我们可以得到 heapq 但这将是一种矫枉过正。附加的 if 子句可用于检查 inner list 是否具有 len >2

答案 1 :(得分:1)

虽然其他人已经发布了非常有用的迭代解决方案,但这里有一种可以递归选择完整目录的方法:

from collections import defaultdict
def to_tree(d):
  t = defaultdict(list)
  for a, *b in d:
     t[a].append(b)
  return {a:None if not (k:=list(filter(None, b))) else to_tree(k) for a, b in t.items()}

def get_paths(d, c = []):
  for a, b in d.items():
     if b is None:
        yield '/'.join(c+[a])
     else:
        yield from get_paths(b, c + [a])


dirnames = ["foo/bar", "foo/bar/mydir", "bar/mydir", "bar"]
print(list(get_paths(to_tree([i.split('/') for i in dirnames]))))

输出:

['foo/bar/mydir', 'bar/mydir']