Мне нужно преобразовать дерево со следующей структурой классов:
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 and (a == 1 and b == 2)) and ((y == 10 and (a == 3)) or (y == 3 and 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?
Я пробовал пару рекурсивных алгоритмов, но не могу заставить их давать необходимый вывод 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
Я могу изменить структуру класса, чтобы сделать проблему более доступной. Какой будет самая простая структура класса, которая даст вывод json?
Я бы выбрал другую начальную структуру. В вашей структуре оператор И или ИЛИ должен иметь экземпляр данных в качестве родителя. И экземпляр Data объединяется с оба и списками И и ИЛИ, которые зависят от него.
Я бы предложил разрешить оператор И или ИЛИ верхнего уровня, у которого все операнды являются дочерними. Вы также можете создать отдельные классы для операторов 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
}
]
}
]
}
]
}
}
}
Я нахожу вашу структуру классов не очень интуитивной (я бы сделал это по-другому). Можете ли вы предоставить сценарий, который создает пример структуры с использованием этих классов?