如何使用Python过滤此树?

时间:2017-05-30 03:56:25

标签: python tree

像树一样有Python数据结构。 我想过滤detect_obj == 1的节点,嵌套ID 8,叶子detect_obj = 0,需要删除,而ID 6和7现在是空的,也需要删除。 如何优雅地做到这一点?

[
    {
        "ID": 1,
        "children": [],
        "detect_obj": 1,
        "isleaf": 1,
        "name": "1",
        "parent_id": None
    },
    {
        "ID": 2,
        "children": [],
        "detect_obj": 1,
        "isleaf": 1,
        "name": "2",
        "parent_id": None
    },
    {
        "ID": 3,
        "children": [],
        "detect_obj": 0,
        "isleaf": 1,
        "name": "3",
        "parent_id": None
    },
    {
        "ID": 4,
        "children": [],
        "detect_obj": 0,
        "isleaf": 1,
        "name": "4",
        "parent_id": None
    },
    {
        "ID": 5,
        "children": [],
        "detect_obj": 0,
        "isleaf": 1,
        "name": "5",
        "parent_id": None
    },
    {
        "ID": 6,
        "children": [
            {
                "ID": 7,
                "children": [
                    {
                        "ID": 8,
                        "children": [],
                        "detect_obj": 0,
                        "isleaf": 1,
                        "name": "8",
                        "parent_id": 7
                    }
                ],
                "detect_obj": None,
                "isleaf": 0,
                "name": "7",
                "parent_id": 6
            }
        ],
        "detect_obj": None,
        "isleaf": 0,
        "name": "6",
        "parent_id": None
    }
]

2 个答案:

答案 0 :(得分:1)

您可以非常轻松地编写递归过滤器函数,该函数可以修改现有树,或者(更轻松地)仅使用您要包含的项创建新的副本。我不确定我是否正确理解了你要过滤的标准,但这是我最好的尝试:

def filter_tree(tree):
    new_tree = []
    for item in tree:
        if item['is_leaf'] == 1 and item['detect_obj'] == 1: # filter leaves on detect_obj
            new_tree.append(item)
        else:
            new_children = filter_tree(item['children']) # recursively filter non-leaf nodes
            if new_children:          # and filter them out if they have no children left
                new_item = item.copy()
                new_item['children'] = new_children
                new_tree.append(new_item)
    return new_tree

此函数将返回树的粗略副本,原始版本保持不变。将复制非叶节点,以便更新其“子”列表,但不会复制叶节点。

答案 1 :(得分:0)

这将使用detect_obj == 1过滤顶级节点。

tree = ...
tree = [node for node in tree if node["detect_obj"] == 1]

这将使用指定的谓词

过滤树的所有级别
def filter_nodes(tree, predicate):
  result = []
  for node in tree:
    if predicate(node):
      clone = node.copy()
      clone['children'] = filter_nodes(clone['children'], predicate)
      result.append(clone)
  return result

tree = ...
print(filter_nodes(tree, lambda node: node['detect_obj'] == 1))