【问题标题】:Iterate over a list to create a parent/child dictionary [closed]迭代列表以创建父/子字典 [关闭]
【发布时间】:2019-01-05 06:31:28
【问题描述】:

假设我有以下列表:

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

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

例子:

['02', 'y', '01'] 中的第三个元素是 '01' 是 'y' 的 parent_key,这意味着它是 '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])

但它不会产生所需的输出

【问题讨论】:

  • 是否需要保留索引键,即0102等?您的二级存储名称而不是键是否有原因?
  • @MisterMiyagi 不,索引键并不重要。我想在没有钥匙的情况下显示父母及其子女/孙子女,如果这有意义吗?
  • 键名和名字是唯一的吗,或者同一个名字可以应用于多个名字?
  • @MisterMiyagi 他们是独一无二的。
  • @MisterMiyagi 不,它们可以出现在列表中的任何位置。

标签: python dictionary


【解决方案1】:

假设每个名字只属于一个键,并且父母定义在他们的孩子之前,你需要为每个元素做三个任务:

  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) 和 parent->child (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.

【讨论】:

  • 当父母和孩子被订购时效果很好。当它们没有被排序时,你的意思是name2children = {name: [] for _, name, _ in l} 会替换for循环之前的空字典吗?
  • 对不起,我错过了name2children key2name 在这种情况下必须事先构建。更新中...
猜你喜欢
  • 2019-07-28
  • 2017-03-25
  • 2013-09-04
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
相关资源
最近更新 更多