遍历 Python 中的层次结构

iterating through hierarchical structures in Python

我在数据集中有一组编号组,这些组是按层次结构组织的。每个组都有一个编号的标题,并且有该组的几个成员。例如:

01 : Tony, John, Meredith
01.01 : Alex, Fred, Melissa
02 : Alley, Henry, Natalie
02.01.02 : Chris, Pete
03 : Andrew
03.01 : Nancy, Peter, Harold

我应该在 python 中使用什么数据结构来组织这些组?我需要维护层次结构,以便 01.01 是 0.1 的 child。数据结构深达 7 层,例如:01.03.01.01.02.04.05,该组是组 01.03.01.01.02.04 的 child,依此类推。任何帮助深表感谢。我不确定要创建什么数据结构,所以我可以迭代它。谢谢

你问"What data structure should I use in python to organize these groups?"

自上而下编程的一个关键原则是,在确定将对结构执行的操作以及它们的相对频率和任何其他标准之前,您不会决定抽象数据结构的实现(例如简单性和内存使用)。您没有说明该信息,因此我们无法推荐特定的实施方式。

我可以想出很多方法来完成您的要求:树、列表中的列表、字典中的字典等等。每种方法都有其优点和缺点。我确实想知道一点。在您的结构中,新子级别的每个项目都以“01”开头,但以“02”开头的“02.01.02 : Chris, Pete”除外。那是故意的吗?如果保留其他明显的编号,则会打开一些更简单的实现。


根据您评论中添加的信息,我推荐嵌套列表。每个 数据项 都有一系列以零结尾的索引,结构中的任何其他内容都是包含其他数据项和列表的列表。在您的示例中,如果我们将整个结构命名为 a,则项目 01 为 a[1][0],项目 01.01 在 a[1][1][0] 中,项目 02.01.02 在 a[2][1][2][0] 中,等等。此结构允许稍后插入更多项目,因此我们可以轻松添加项目 01.01.01 而不会干扰其他项目。不需要在结构中存储项目编号:它们直接从数据项在结构中的位置推断出来。

这个实现还允许整个结构有一个数据项,它有一个空的项号并存储在a[0]中。缺失的数据项可以用 None 标记,空白项可以是另一个空项,例如 ''。这是显示示例结构的代码和打印出来的代码。

def print_structure(structure, level=''):
    """Iterate through a heirarchical data structure, printing the data
       items with their level numbers"""
    for i, item in enumerate(structure):
        if i == 0:
            # Process each data item appropriately
            if item is not None:
                print(level + ' : ' + str(item))
        else:
            new_level = format(i, '02')
            if level:
                new_level = level + '.' + new_level
            print_structure(item, new_level)


a = [None,
     ['Tony, John, Meredith',
      ['Alex, Fred, Melissa']],
     ['Alley, Henry, Natalie',
      [None,
       ['?'],
       ['Chris, Pete']]],
     ['Andrew',
      ['Nancy, Peter, Harold']]]

print_structure(a)

在此实现中,您的每个 "groups" 都是一个字符串。我把组 '?' 放在你说存在组但没有说明它是什么的地方,我把 None 放在你没有说存在数据项的地方。修改结构体的处理,只需要修改注释Process each data item appropriately后面的两行即可。上面代码的打印输出是

01 : Tony, John, Meredith
01.01 : Alex, Fred, Melissa
02 : Alley, Henry, Natalie
02.01.01 : ?
02.01.02 : Chris, Pete
03 : Andrew
03.01 : Nancy, Peter, Harold

保存到 JSON 和从 JSON 恢复很容易。这应该可以满足您的需求,当然,可以对结构或代码进行一些修改。

如果您的主要目标是生成一个可以写出的 JSON-friendly 结构,请使用嵌套字典(如果元素的顺序很重要,则使用 OrderedDict)。它使事情变得简单,用 json 写出来将是微不足道的。每个字典可以有一个键 members(直接分配给它的 children 的列表或集合),以及 sub-dictionaries 的列表或字典的键 subgroups .创建起来并不难,因为 parent 组的标题是子组的前缀。