dictionnary的路径列表

时间:2018-05-15 09:10:00

标签: python dictionary path

我正在尝试从路径列表中填充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 = {}
?

非常感谢您提前

4 个答案:

答案 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)

我有一个替代递归解决方案。对于每条路径:

  • 将光标放在目标字典
  • 的根目录下
  • 搜索序列:向前移动光标,直到找到路径的0或缺失部分
  • 构建序列:添加一个空字典并将光标移动到该字典上,直到你击中最后一部分。
  • 最后一部分需要对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))