python-3.x - 从任意嵌套的 xml 树总和返回结果
问题描述
我有以下代码在 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)
返回的东西然后被扔掉的线。由于您可以获得返回的数字列表,应该添加/相乘/等,您可以将这些添加到numbers
列表中numbers.extend(somelist)
。解释递归有点困难,所以如果你看一下代码,它可能会更有意义。我有时做的是depth
向函数添加一个变量,并在每次“递归”时递增它 - 这样,在打印信息时,可能更容易查看数字从哪个“级别”返回以及返回到何处。
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 个数字,因为它是二元运算,然后依赖嵌套。显然同样适用于其他一元/二元/三元/.. 运算符。
<add>
<number>1</number>
<add>
<number>2</number>
<number>3</number>
</add>
</add>
这样,也许您可以消除 for 循环,但我不确定它是否会产生其他问题。:-)
推荐阅读
- c++ - 如何从 popen 获取未找到和权限错误
- reactjs - 当我们在 NextJs 应用程序中更改路由时,后续页面是否也可以抓取 (SEO)?
- reactjs - Ionic + React 使用离子硬件后退按钮关闭 Cupertino 窗格或任何第三方覆盖或模态
- python - 使用向导 Odoo11 记录内部注释
- geth - geth 在哪里存储 SNAPSHOT 数据
- python - 在 Python 中制作 Netcat - 错误的文件描述符 [Errno 9]
- azure - Azure 应用程序网关 - 基于浴缸的路由
- sql - MySql 事件未更新表列
- postgresql - 如何配置 HaProxy 以平衡对 PostgreSQL 集群所有节点的读取请求?
- powershell - VScode 调试器 - powershell 集成控制台无法启动:无法加载模块“Microsoft.PowerShell.Security”