我有一个目录名称列表:
dirnames = ["foo/bar", "foo/bar/mydir", "bar/mydir", "bar"]
我想(递归地)创建所有目录。只需要递归地创建最深的目录就足够了。在这种情况下,只需:
os.makedirs("foo/bar/mydir")
os.makedirs("bar/mydir")
问题:如何将 dirnames
减少到只有最深的目录?
答案 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
。即 foo
或 bar
。如果我们使用 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']