Return 来自任意嵌套 xml 树总和的结果
Return result from arbitrarily nested xml tree sum
我有以下代码在 xml 树上递归(?),它表示一个简单的等式:
root = etree.XML(request.data['expression'])
def addleafnodes(root):
numbers = []
for child in root:
if root.tag != "root" and root.tag != "expression":
print(root.tag, child.text)
if child.tag != "add" and child.tag != "multiply":
numbers.append(int(child.text))
print("NUMBERS", numbers)
elif child.tag == "add":
numbers.append(np.sum(addleafnodes(child)))
print("NUMBERS", numbers)
elif child.tag == "multiply":
numbers.append(np.prod(addleafnodes(child)))
print("NUMBERS", numbers)
print("NUMBERS", numbers)
addleafnodes(child)
return numbers
newresults = addleafnodes(root)
print("[NEW RESULTS]", newresults)
xml是:
<root>
<expression>
<add>
<add>
<number>1</number>
<number>2</number>
</add>
<multiply>
<number>2</number>
<number>3</number>
</multiply>
<add>
<number>4</number>
<number>5</number>
</add>
<number>3</number>
<multiply>
<number>1</number>
<add>
<number>3</number>
<number>4</number>
</add>
</multiply>
</add>
</expression>
</root>
代码似乎一直运行到最后一个循环,当它重置数字列表并似乎再次启动该过程时,失败了。
如何让 python (lxml) 在检查完每个节点后停止?我可能错过了一些重要的事情!
首先,我认为您可以通过断言标签 是 而不是 不是 来让自己更轻松成为某种东西(例如,尝试删除 != 并替换为 ==)。
一个问题是 addleafnodes(child)
行,它返回了一些东西,但后来又被扔掉了。由于您可以获得返回的数字列表,它应该是 added/multiplied/etc。您可以使用 numbers.extend(somelist)
将它们添加到 numbers
列表中。解释递归有点困难,所以如果你看一下代码,它可能会更有意义。我有时做的是在函数中添加一个 depth
变量并在每次我 "recurse" 时递增它 - 这样,在打印信息时,可能更容易看到哪个 "level" 数字是从哪里回来。
def addleafnodes(root):
numbers = []
for child in root:
if child.tag == "number":
numbers.append(int(child.text))
elif child.tag == "add":
numbers.append(np.sum(addleafnodes(child)))
elif child.tag == "multiply":
numbers.append(np.prod(addleafnodes(child)))
else:
numbers.extend(addleafnodes(child))
print("NUMBERS: ", numbers)
return numbers
newresults = addleafnodes(root)
print("[NEW RESULTS]", newresults)
# outputs:
NUMBERS: [1]
NUMBERS: [1, 2]
NUMBERS: [3]
NUMBERS: [2]
NUMBERS: [2, 3]
NUMBERS: [3, 6]
NUMBERS: [4]
NUMBERS: [4, 5]
NUMBERS: [3, 6, 9]
NUMBERS: [3, 6, 9, 3]
NUMBERS: [1]
NUMBERS: [3]
NUMBERS: [3, 4]
NUMBERS: [1, 7]
NUMBERS: [3, 6, 9, 3, 7]
NUMBERS: [28]
NUMBERS: [28]
[NEW RESULTS] [28]
另一件事:您已选择允许 <add></add>
中的数字列表。你也可以认为它只有 2 个数字,因为它是一个二元运算,然后依赖于嵌套。同样显然适用于其他 unary/binary/ternary/.. 运营商。
<add>
<number>1</number>
<add>
<number>2</number>
<number>3</number>
</add>
</add>
这样,也许您可以消除 for-loop,但我不确定它是否会产生其他问题。 :-)
我有以下代码在 xml 树上递归(?),它表示一个简单的等式:
root = etree.XML(request.data['expression'])
def addleafnodes(root):
numbers = []
for child in root:
if root.tag != "root" and root.tag != "expression":
print(root.tag, child.text)
if child.tag != "add" and child.tag != "multiply":
numbers.append(int(child.text))
print("NUMBERS", numbers)
elif child.tag == "add":
numbers.append(np.sum(addleafnodes(child)))
print("NUMBERS", numbers)
elif child.tag == "multiply":
numbers.append(np.prod(addleafnodes(child)))
print("NUMBERS", numbers)
print("NUMBERS", numbers)
addleafnodes(child)
return numbers
newresults = addleafnodes(root)
print("[NEW RESULTS]", newresults)
xml是:
<root>
<expression>
<add>
<add>
<number>1</number>
<number>2</number>
</add>
<multiply>
<number>2</number>
<number>3</number>
</multiply>
<add>
<number>4</number>
<number>5</number>
</add>
<number>3</number>
<multiply>
<number>1</number>
<add>
<number>3</number>
<number>4</number>
</add>
</multiply>
</add>
</expression>
</root>
代码似乎一直运行到最后一个循环,当它重置数字列表并似乎再次启动该过程时,失败了。
如何让 python (lxml) 在检查完每个节点后停止?我可能错过了一些重要的事情!
首先,我认为您可以通过断言标签 是 而不是 不是 来让自己更轻松成为某种东西(例如,尝试删除 != 并替换为 ==)。
一个问题是 addleafnodes(child)
行,它返回了一些东西,但后来又被扔掉了。由于您可以获得返回的数字列表,它应该是 added/multiplied/etc。您可以使用 numbers.extend(somelist)
将它们添加到 numbers
列表中。解释递归有点困难,所以如果你看一下代码,它可能会更有意义。我有时做的是在函数中添加一个 depth
变量并在每次我 "recurse" 时递增它 - 这样,在打印信息时,可能更容易看到哪个 "level" 数字是从哪里回来。
def addleafnodes(root):
numbers = []
for child in root:
if child.tag == "number":
numbers.append(int(child.text))
elif child.tag == "add":
numbers.append(np.sum(addleafnodes(child)))
elif child.tag == "multiply":
numbers.append(np.prod(addleafnodes(child)))
else:
numbers.extend(addleafnodes(child))
print("NUMBERS: ", numbers)
return numbers
newresults = addleafnodes(root)
print("[NEW RESULTS]", newresults)
# outputs:
NUMBERS: [1]
NUMBERS: [1, 2]
NUMBERS: [3]
NUMBERS: [2]
NUMBERS: [2, 3]
NUMBERS: [3, 6]
NUMBERS: [4]
NUMBERS: [4, 5]
NUMBERS: [3, 6, 9]
NUMBERS: [3, 6, 9, 3]
NUMBERS: [1]
NUMBERS: [3]
NUMBERS: [3, 4]
NUMBERS: [1, 7]
NUMBERS: [3, 6, 9, 3, 7]
NUMBERS: [28]
NUMBERS: [28]
[NEW RESULTS] [28]
另一件事:您已选择允许 <add></add>
中的数字列表。你也可以认为它只有 2 个数字,因为它是一个二元运算,然后依赖于嵌套。同样显然适用于其他 unary/binary/ternary/.. 运营商。
<add>
<number>1</number>
<add>
<number>2</number>
<number>3</number>
</add>
</add>
这样,也许您可以消除 for-loop,但我不确定它是否会产生其他问题。 :-)