字典的路径列表

2024-06-25 06:37:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从路径列表中填充python dict(目的是创建一个ttk.treview公司)地址:

paths = ["\\hihi", "\\hihi\\hoho\\huhu", "\\hihi\\hoho\\haha", "\\haha", "\\huhu"]

我想创建这个dictionary(json在这里序列化):

{
   "haha": {},
   "hihi": {
       "hoho": {
           "huhu": 0
       },
       "huhu": {
           "haha": 0
       }
   },
   "huhu": {}
}

最好的方法是什么?我尝试了for循环(递归循环?)但我没有有效的结果。你知道吗

我的代码的双重性:

split = paths.split("\\")
del split[0]
dict = {}
?

事先非常感谢


Tags: 路径目的列表dictionary地址公司dictsplit
1条回答
网友
1楼 · 发布于 2024-06-25 06:37:25

您可以使用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)
网友
2楼 · 发布于 2024-06-25 06:37:25

可以将递归与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楼 · 发布于 2024-06-25 06:37:25

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

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

相关问题 更多 >