从树数据中查找根节点

时间:2019-03-12 06:09:49

标签: python tree graph-theory

我有以下课程:

class Category(object):
    def __init__(self, *args, **kwargs):
        self.id = kwargs.get('id')
        self.name = kwargs.get('name')
        self.parent_id = kwargs.get('parent_id', None)

    def get_top_parent_category(self, obj_list):
        # This algorithm is using extensive resource 
        category = self
        while category.parent_id:
            def filter_func(obj):
                return obj.id == category.parent_id
            parent = list(filter(filter_func, obj_list))

            category = parent[0]
        return category

    @classmethod
    def all(cls):
        url = BASE_URL + '/api/v1/categories/'
        response = requests.get(url, headers=headers, verify=False)
        if not response.status_code == 200:
            raise Exception('Error')
        categories = response.json()
        _temp_categories = []
        for _i in categories['results']:
            _temp_categories.append(cls(**_i))
        return _temp_categories

我按以下方式获取所有类别

all_categories = Category.all()

现在我需要找到提供的任何类别的根节点。

category = Category(**category_data)
category.get_top_parent_category(all_categories)

我得到了预期的结果,但是我觉得使用图论

可能有一些更好的方法来找到根节点

解决这个问题的更好方法是什么?

1 个答案:

答案 0 :(得分:0)

如果您需要对其进行更多与树相关的处理,则可能希望将Category对象彼此链接,而不是通过父标识符进行间接链接。

但是在您发布的代码中,主要问题是这些重复的调用,您必须在其中扫描整个对象列表:

parent = list(filter(filter_func, obj_list))

如果将其替换为字典,则性能会好很多,因为单亲的查找时间为〜恒定时间

例如仅举例来说

parent_map = dict([(c.id, c) for c in obj_list])

(显然,在get_top_parent_category()方法中不要这样做,因为它同样昂贵)

然后可以通过以下简单操作来查找类别的父项:

parent = parent_map[parent.id]

您现在拥有的同一循环将以这种方式快一个数量级。