将复杂的树结构转换为Json Python

发布于 2025-01-18 04:38:19 字数 4113 浏览 0 评论 0原文

我需要转换具有以下类结构的树:

Class Tree:     
    def __init__(self, data):         
        self.data = data         
        self.and_objects = []         
        self.or_objects = []

数据是:

Class Data:     
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
    def to_json(self):
        return {"var": self.var, "operator": self.operator, "value": self.value}

数据结构的简化示例:

Root
  andChildren
    x = 0
      andChildren
         a = 1
         b = 2 
    y = 10
      andChildren
         a = 3   
      orChildren
         y = 3
            andChildren
               a = 2
         
  orChildren
    Empty

此评估为:

((x == 0和(a == 1 and B == 2)) )和((y == 10和(a == 3))或(y == 3和a == 2))

我需要将树数据结构转换为:

{
   "Search":{
      "Root":{
         "compare_operator":"and",
         "values":[
            {
               "compare_operator":"and",
               "values":[
                  {
                     "var":"x",
                     "operator":"=",
                     "value":"0"
                  },
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"1"
                        },
                        {
                           "var":"b",
                           "operator":"=",
                           "value":"2"
                        }
                     ]
                  }
               ]
            },
            {
               "compare_operator":"or",
               "values":[
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"y",
                           "operator":"=",
                           "value":"10"
                        },
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"3"
                        }
                     ]
                  },
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"y",
                           "operator":"=",
                           "value":"3"
                        },
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"2"
                        }
                     ]
                  }
               ]
            }
         ]
      }
   }
}

有人有任何提示/方法关于如何将这棵树数据结构转换为此JSON

结构


Class Tree:     
    def __init__(self, data="root"):         
        self.data = data         
        self.and_objects = []         
        self.or_objects = []
        
Class Data:     
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
    def to_json(self):
        return {"var": self.var, "operator": self.operator, "value": self.value}
        
def create_search(var, operator, value, parent, comparision="and")
    data = Data(var, operator, value)
    child = Tree(data)
    if comparision == "and":
        parent.and_objects.append(child)
    else:
        parent.or_objects.append(child)
    return child
    
if __name__ == "__main__":
    root_tree = Tree()
    x_temp = create_search("x", "=", "0", root_tree)
    create_search("a", "=", "1", x_temp)
    create_search("b", "=", "2", x_temp)
    
    y_temp = create_search("y", "=", "10", root_tree)
    create_search("a", "=", "3", root_tree, y_temp)
    nested_y_temp = create_search("y", "=", "3", root_tree, y_temp, "or")
    create_search("a", "=", "2", root_tree, nested_y_temp)
    
    # tree data is on root_tree

I need to convert a Tree with the following class structure:

Class Tree:     
    def __init__(self, data):         
        self.data = data         
        self.and_objects = []         
        self.or_objects = []

Where the data is:

Class Data:     
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
    def to_json(self):
        return {"var": self.var, "operator": self.operator, "value": self.value}

A simplified example of the data structure:

Root
  andChildren
    x = 0
      andChildren
         a = 1
         b = 2 
    y = 10
      andChildren
         a = 3   
      orChildren
         y = 3
            andChildren
               a = 2
         
  orChildren
    Empty

This evaluates to:

((x == 0 and (a == 1 and b == 2)) and ((y == 10 and (a == 3)) or (y == 3 and a == 2))

I need to convert the tree data structure to:

{
   "Search":{
      "Root":{
         "compare_operator":"and",
         "values":[
            {
               "compare_operator":"and",
               "values":[
                  {
                     "var":"x",
                     "operator":"=",
                     "value":"0"
                  },
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"1"
                        },
                        {
                           "var":"b",
                           "operator":"=",
                           "value":"2"
                        }
                     ]
                  }
               ]
            },
            {
               "compare_operator":"or",
               "values":[
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"y",
                           "operator":"=",
                           "value":"10"
                        },
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"3"
                        }
                     ]
                  },
                  {
                     "compare_operator":"and",
                     "values":[
                        {
                           "var":"y",
                           "operator":"=",
                           "value":"3"
                        },
                        {
                           "var":"a",
                           "operator":"=",
                           "value":"2"
                        }
                     ]
                  }
               ]
            }
         ]
      }
   }
}

Does anyone have any tips/methods on how to transform this tree data structure to this json structure?

I've tried a couple recursive algorithms, but I can not get them to yield the JSON output needed.

The script that recreates this structure:


Class Tree:     
    def __init__(self, data="root"):         
        self.data = data         
        self.and_objects = []         
        self.or_objects = []
        
Class Data:     
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
    def to_json(self):
        return {"var": self.var, "operator": self.operator, "value": self.value}
        
def create_search(var, operator, value, parent, comparision="and")
    data = Data(var, operator, value)
    child = Tree(data)
    if comparision == "and":
        parent.and_objects.append(child)
    else:
        parent.or_objects.append(child)
    return child
    
if __name__ == "__main__":
    root_tree = Tree()
    x_temp = create_search("x", "=", "0", root_tree)
    create_search("a", "=", "1", x_temp)
    create_search("b", "=", "2", x_temp)
    
    y_temp = create_search("y", "=", "10", root_tree)
    create_search("a", "=", "3", root_tree, y_temp)
    nested_y_temp = create_search("y", "=", "3", root_tree, y_temp, "or")
    create_search("a", "=", "2", root_tree, nested_y_temp)
    
    # tree data is on root_tree

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

向日葵 2025-01-25 04:38:19

我会选择不同的初始结构。在您的结构中,AND 或 OR 运算符需要有一个 Data 实例作为父级。数据实例与依赖于它的两者以及 AND 和 OR 列表组合在一起。

我建议允许顶级 AND 或 OR 运算符将其所有操作数作为子项。您还可以为 AND 和 OR 运算符以及 EQUALITY 运算符创建单独的类。

class Logical():
    def __init__(self, operator, operands):
        self.operands = operands
        self.operator = operator

    def __str__(self):
        return f" {self.operator} ".join(map(str, self))

    def asdict(self):
        return { 
            "compare_operator": self.operator, 
            "values": [operand.asdict() for operand in self.operands]
        }

class And(Logical):
    def __init__(self, *operands):
        super().__init__("and", operands)

class Or(Logical):
    def __init__(self, *operands):
        super().__init__("or", operands)


class Condition:
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
        
    def asdict(self):
        return {
            "var": self.var, 
            "operator": self.operator, 
            "value": self.value
        }

class Equal(Condition):
    def __init__(self, var, value):
        super().__init__(var, "=", value)

结构的创建示例:

expression = And(
    And(
        Equal("x", 0), 
        And(
            Equal("a", 1), 
            Equal("b", 2), 
        ),
    ),
    Or(
        And(
            Equal("y", 10), 
            Equal("a", 3)
        ),
        And(
            Equal("y", 3),
            Equal("a", 2)
        )
    )
)

其转换为 JSON:

import json

result = {
    "Search": {
        "Root": expression.asdict()
    }
}

print(json.dumps(result, indent=4))

这将打印:

{
    "Search": {
        "Root": {
            "compare_operator": "and",
            "values": [
                {
                    "compare_operator": "and",
                    "values": [
                        {
                            "var": "x",
                            "operator": "=",
                            "value": 0
                        },
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 1
                                },
                                {
                                    "var": "b",
                                    "operator": "=",
                                    "value": 2
                                }
                            ]
                        }
                    ]
                },
                {
                    "compare_operator": "or",
                    "values": [
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "y",
                                    "operator": "=",
                                    "value": 10
                                },
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 3
                                }
                            ]
                        },
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "y",
                                    "operator": "=",
                                    "value": 3
                                },
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 2
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

I would go for a different initial structure. In your structure an AND or OR operator needs to have a Data instance as parent. And a Data instance is combined with both and AND and OR list that depends on it.

I would suggest to allow for a top-level AND or OR operator that has all its operands as children. You could also create separate classes for AND and OR operators, and for EQUALITY operator as well.

Here is how that would look:

class Logical():
    def __init__(self, operator, operands):
        self.operands = operands
        self.operator = operator

    def __str__(self):
        return f" {self.operator} ".join(map(str, self))

    def asdict(self):
        return { 
            "compare_operator": self.operator, 
            "values": [operand.asdict() for operand in self.operands]
        }

class And(Logical):
    def __init__(self, *operands):
        super().__init__("and", operands)

class Or(Logical):
    def __init__(self, *operands):
        super().__init__("or", operands)


class Condition:
    def __init__(self, var, operator, value):
        self.var = var
        self.operator = operator
        self.value = value
        
    def asdict(self):
        return {
            "var": self.var, 
            "operator": self.operator, 
            "value": self.value
        }

class Equal(Condition):
    def __init__(self, var, value):
        super().__init__(var, "=", value)

Example creation of a structure:

expression = And(
    And(
        Equal("x", 0), 
        And(
            Equal("a", 1), 
            Equal("b", 2), 
        ),
    ),
    Or(
        And(
            Equal("y", 10), 
            Equal("a", 3)
        ),
        And(
            Equal("y", 3),
            Equal("a", 2)
        )
    )
)

Turning it to JSON:

import json

result = {
    "Search": {
        "Root": expression.asdict()
    }
}

print(json.dumps(result, indent=4))

This prints:

{
    "Search": {
        "Root": {
            "compare_operator": "and",
            "values": [
                {
                    "compare_operator": "and",
                    "values": [
                        {
                            "var": "x",
                            "operator": "=",
                            "value": 0
                        },
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 1
                                },
                                {
                                    "var": "b",
                                    "operator": "=",
                                    "value": 2
                                }
                            ]
                        }
                    ]
                },
                {
                    "compare_operator": "or",
                    "values": [
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "y",
                                    "operator": "=",
                                    "value": 10
                                },
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 3
                                }
                            ]
                        },
                        {
                            "compare_operator": "and",
                            "values": [
                                {
                                    "var": "y",
                                    "operator": "=",
                                    "value": 3
                                },
                                {
                                    "var": "a",
                                    "operator": "=",
                                    "value": 2
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文