在树中找到父节点

时间:2019-12-05 13:56:57

标签: python python-3.x recursion yield

我创建了一个JSON示例,我想输入一个ID并获取该商品和所有父母。 尽管我的代码确实可以工作,但它并不具有Python风格,但必须有更好的方法。

a_list = [
    {
        "name": {"en": "Canada"},
        "id": "CAN",
        "children": [
            {
                "name": {"en": "British Columbia"},
                "id": "01",
                "children": [
                    {"name": {"en": "Vancouver"}, "id": "10", "children": []},
                    {"name": {"en": "Victoria"}, "id": "11", "children": []}
                ]
            },
            {
                "name": {"en": "Nova Scotia"},
                "id": "02",
                "children": [
                    {"name": {"en": "Halifax"}, "id": "13", "children": []}
                ]
            }
        ],
        "name": {"en": "USA"},
        "id": "US",
        "children": [
            {
                "name": {"en": "Virgina"},
                "id": "VA",
                "children": [
                    {"name": {"en": "Richmond"}, "id": "20", "children": []},
                    {"name": {"en": "Norfolk"}, "id": "21", "children": []}
                ]
            },
            {
                "name": {"en": "Maryland"},
                "id": "MD",
                "children": [
                    {"name": {"en": "Baltimore"}, "id": "23", "children": []},
                    {"name": {"en": "Gaithersburg"}, "id": "24", "children": []}
                ]
            }
        ]
    }
]

所以我创建了这个功能

def find_item_and_parents_in_list(value, items):
    item_found = []
    for item in items:
        if item['id'] == value:
            item_found.append(item)
        else:
            item_list = find_item_and_parents_in_list(value, item['children'])
            if item_list:
                item_list.append(item)
                item_found = item_list

    return item_found

如果我使用它,即

items = find_item_in_list("23", a_list)
for item in items:
   print(item['id'])

它返回 23 医学博士 美国

但是我的find_item_and_parents_in_list可以用更好的方式编写吗?以收益为例

1 个答案:

答案 0 :(得分:0)

您可以将递归与生成器一起使用:

def get_paths(d, _id, c = []):
   if d['id'] == _id:
      yield c+[_id]
   yield from [i for b in d['children'] for i in get_paths(b, _id, c+[d['id']])]

print(list(get_paths(a_list[0], '23'))[0])

输出:

['US', 'MD', '23']