如何匹配多个列表中的值以创建树

时间:2018-05-17 07:55:54

标签: python list

我有一份清单

tree = [
    15 [
        19 [
            642: {3974},
            643: {3975},
        ],
        20 [
            642: {1315},
            643: {3973},
        ],
    ],
    16 [
        19 [
            642: {3978},
            643: {3979},
        ],
        20 [
            642: {3976},
            643: {3977},
        ],
    ],
    17 [
        19 [
            642: {3982},
            643: {3983},
        ],
        20 [
            642: {3980},
            643: {3981},
        ],
    ],
    18 [
        19 [
            642: {3986},
            643: {3987},
        ],
        20 [
            642: {3984},
            643: {3985},
        ],
    ]
]

我想创建一个看起来像这样的树

if(doc.SelectSingleNode("/a/b")!=null)

我不知道如何使用Python的工具来实现这一目标。我不需要优雅,但我只需要匹配所有这些列表来创建树多列表。

3 个答案:

答案 0 :(得分:1)

您可以使用以下递归函数创建字典词典:

def add_path(idx, path, res_dict):
    node_dict = path[idx]
    key = node_dict['option_id']
    if 'article_id' in node_dict:
        res_dict[key] = node_dict['article_id']
    else:
        if key not in res_dict:
            res_dict[key] = dict()
        add_path(idx + 1, path, res_dict[key])


def option_tree(option_arr):
    result = dict()
    for path in option_arr:
        add_path(0, path, result)
    return result

使用示例输入调用时,您将获得以下字典:

{
15: {
    20: {
            642: 1315,
            643: 3973
        },
    19: {
            642: 3974,
            643: 3975
        }
    },
16: {
    20: {
            642: 3976,
            643: 3977
        },
    19: {
            642: 3978,
            643: 3979
        }
    },
17: {
    20: {
            642: 3980,
            643: 3981
        },
    19: {
            642: 3982,
            643: 3983
        }
    },
18: {
    20: {
            642: 3984,
            643: 3985
        },
    19: {
            642: 3986,
            643: 3987
        }
    }
}

并且可以获得特定值result[15][20][643]

答案 1 :(得分:1)

您可以非常轻松地构建类似于嵌套字典的内容:

tree = {}
for row in arr:
    d = tree
    for id_dict in row:
        if 'article_id' in id_dict:
            d.setdefault(id_dict['option_id'], []).append(id_dict['article_id'])
        else:
            d = d.setdefault(id_dict['option_id'], {})

如果您的option_id组合都是唯一的,那么您可以摆脱最里面的列表。只需将行d.setdefault(id_dict['option_id'], []).append(id_dict['article_id'])替换为更简单的d[id_dict['option_id']] = id_dict['article_id']

答案 2 :(得分:-1)

您可以将itertools.groupby与递归一起使用:

import itertools

arr = [[{'option_id': 15L}, {'option_id': 20L}, {'article_id': 1315L, 'option_id': 642L}], [{'option_id': 15L}, {'option_id': 20L}, {'article_id': 3973L, 'option_id': 643L}], [{'option_id': 15L}, {'option_id': 19L}, {'article_id': 3974L, 'option_id': 642L}], [{'option_id': 15L}, {'option_id': 19L}, {'article_id': 3975L, 'option_id': 643L}], [{'option_id': 16L}, {'option_id': 20L}, {'article_id': 3976L, 'option_id': 642L}], [{'option_id': 16L}, {'option_id': 20L}, {'article_id': 3977L, 'option_id': 643L}], [{'option_id': 16L}, {'option_id': 19L}, {'article_id': 3978L, 'option_id': 642L}], [{'option_id': 16L}, {'option_id': 19L}, {'article_id': 3979L, 'option_id': 643L}], [{'option_id': 17L}, {'option_id': 20L}, {'article_id': 3980L, 'option_id': 642L}], [{'option_id': 17L}, {'option_id': 20L}, {'article_id': 3981L, 'option_id': 643L}], [{'option_id': 17L}, {'option_id': 19L}, {'article_id': 3982L, 'option_id': 642L}], [{'option_id': 17L}, {'option_id': 19L}, {'article_id': 3983L, 'option_id': 643L}], [{'option_id': 18L}, {'option_id': 20L}, {'article_id': 3984L, 'option_id': 642L}], [{'option_id': 18L}, {'option_id': 20L}, {'article_id': 3985L, 'option_id': 643L}], [{'option_id': 18L}, {'option_id': 19L}, {'article_id': 3986L, 'option_id': 642L}], [{'option_id': 18L}, {'option_id': 19L}, {'article_id': 3987L, 'option_id': 643L}]]
def create_tree(d):
  s = [[a, list(b)] for a, b in itertools.groupby(d, key=lambda x:x[0]['option_id'])]
  return {int(a):{int(b[0][0]['article_id'])} if len(b) == 1 else create_tree([i[1:] for i in b]) for a, b in s}

结果:

import pprint
pprint.pprint(create_tree(arr))

输出:

{15: {19: {642: set([3974]), 643: set([3975])},
    20: {642: set([1315]), 643: set([3973])}},
 16: {19: {642: set([3978]), 643: set([3979])},
    20: {642: set([3976]), 643: set([3977])}},
 17: {19: {642: set([3982]), 643: set([3983])},
    20: {642: set([3980]), 643: set([3981])}},
 18: {19: {642: set([3986]), 643: set([3987])},
    20: {642: set([3984]), 643: set([3985])}}}