我正在尝试从路径列表中填充python dict(目的是创建一个ttk.treview):
paths = ["\\hihi", "\\hihi\\hoho\\huhu", "\\hihi\\hoho\\haha", "\\haha", "\\huhu"]
我想创建这个词典(json序列化在这里):
{
"haha": {},
"hihi": {
"hoho": {
"huhu": 0
},
"huhu": {
"haha": 0
}
},
"huhu": {}
}
最好的方法是什么?我尝试使用for循环(递归循环?),使用dict理解和dpath,但我没有有效的结果。
我的代码很重要:
split = paths.split("\\")
del split[0]
dict = {}
?
非常感谢您提前
答案 0 :(得分:1)
您可以使用defaultdict
:
def make_empty_default_dict():
return defaultdict(make_empty_default_dict)
定义添加路径的方式:
def add_path(pth, dct):
if pth:
subdict = dct[pth[0]]
return add_path(pth[1:], subdict)
else:
return dct
然后使用键填充默认dict:
d = make_empty_default_dict()
for path in paths:
d = add_path(path.split("\\"), d)
答案 1 :(得分:0)
我有一个替代递归解决方案。对于每条路径:
以下是代码:
def build_paths(paths, d={}):
for path in paths:
parts = path.split("\\")[1:] # remove the part before \
cursor = d
search = True
for part in parts[:-1]:
if search:
if part not in cursor or not cursor[part]: # not found or 0
cursor[part] = {} # set a new dict
search = False
else:
cursor[part] = {}
cursor = cursor[part] # advance one level deeper in the dict
cursor[parts[-1]] = 0 # close with a 0
return d
它比@xtofl的递归版本快,但不是那么快。使用timeit
:
iterative: 6.169872568580601
recursive: 17.209112331781498
答案 2 :(得分:0)
您可以在itertools.groupby
使用递归:
import itertools
paths = ["\\hihi", "\\hihi\\hoho\\huhu", "\\hihi\\hoho\\haha", "\\haha", "\\huhu"]
new_paths = [list(filter(None, i.split('\\'))) for i in paths]
def update_output(f):
def wrapper(_d):
result = f(_d)
final = lambda x, level = 0:{a:{} if not level and not b else b if not b else final(b, level+1) for a, b in x.items()}
return final(result)
return wrapper
@update_output
def full_directory(data):
def files(d):
return {a:(lambda x:0 if len(x) == 1 else files([i[1:] for i in filter(lambda y:len(y) != 1 or y[0] != a, x)]))(list(b)) for a, b in itertools.groupby(sorted(d, key=lambda x:x[0]), key=lambda x:x[0])}
return files(data)
print(full_directory(new_paths))
输出:
{'haha': {}, 'hihi': {'hoho': {'haha': 0, 'huhu': 0}}, 'huhu': {}}
答案 3 :(得分:-1)
我发现了这个:http://connor-johnson.com/2015/02/28/generate-a-tree-structure-in-python/
效果很好!所以代码:
def add(t, path):
for node in path:
t = t[node]
Tree = lambda: defaultdict(Tree)
t = Tree()
paths = ["\\hihi", "\\hihi\\hoho\\huhu", "\\hihi\\hoho\\haha", "\\haha", "\\huhu"]
for path in paths:
split = path.split("\\")
del split[0]
for elt in split:
add(t, split)
dicts = lambda t: { k:dicts(t[k]) for k in t }
print(json.dumps(dicts(t), indent=4))