代码之家  ›  专栏  ›  技术社区  ›  mallet

遍历列表以创建父/子字典[已关闭]

  •  -4
  • mallet  · 技术社区  · 8 年前

    假设我有以下清单:

    l = [['01', 'pharma', 'P'],['02', 'y', '01'],['03', 'x', '01'],['05', 'z', '03']]
    

    其中每个嵌套列表中的元素分别是key、name和parent_key。如果父项是“P”,则表示它是父项。

    例子:

    ['02','y','01']中的第三个元素是'01'是'y'的父项,这意味着它是'pharma'的子项,而'01'是键。

    我想创建一个父/子词典,可以查询该词典以打印以下内容:

    pharma
     x
      z
     y
    

    其中“pharma”是父级,“x”和“y”是“pharma”的子级,“z”是“x”的子级。每个子项都比其父项缩进一个空格。

    我试过的是:

    from collections import defaultdict
    d = defaultdict(list)
    for i in l:
        d[i[0]] = []
        if i[2] in d.keys():
            d[i[2]].append(i[1])
    

    但它不能产生所需的输出

    1 回复  |  直到 8 年前
        1
  •  1
  •   MisterMiyagi    8 年前

    假设每个名称只属于一个键,并且父项在其子项之前定义,则需要执行以下操作 每个元素的任务:

    1. 将其名称映射到尚未完成的子列表
    2. 将其ID映射到其名称
    3. 将其链接到其父级

    如果父对象和子对象未排序,即子对象可以出现在其父对象之前,则必须生成1。和2。与3分开。 否则,您可以在一次传递数据中完成所有操作。请注意,您可以对for循环中的元素进行结构分解,而不是对元素进行索引。

    key2name = {}
    name2children = {}
    for key, name, parent in l:
        name2children[name] = []  # 1.
        key2name[key] = name      # 2.
        if parent != 'P':         # root node has no parent
            name2children[key2name[parent]].append(name) # 3.
    

    对于您的示例,这将生成结构

    {'pharma': ['y', 'x'], 'x': ['z'], 'y': [], 'z': []}
    

    请注意,您的数据是 排序以匹配所需的输出!


    你可以在这棵树上随意打印。这个 sorted 如果您不介意点菜,可以挂断电话。

    def printwalk(node, indent=0):
        print(' '*indent, node)
        for child in sorted(name2children[node]):
            printwalk(child, indent+1)
    printwalk('pharma')
    # pharma
    #  x
    #   z
    #  y
    

    如果父母和孩子没有得到命令,情况就是这样。您必须分别初始化转换(1)和父容器->子容器(2)。

    key2name = {}
    name2children = {}
    for key, name, _ in l:
        name2children[name] = []  # 1.
        key2name[key] = name      # 2.
    
    for key, name, parent in l:
        if parent != 'P':         # root node has no parent
            name2children[key2name[parent]].append(name) # 3.