我一直在这里查看关于 zip 和魔法 * 的其他问题,这对我理解它是如何工作的有很大帮助。例如:
- 为什么 x,y = zip(*zip(a,b)) 在 Python 中工作?
- zip(*[iter(s)]*n) 在 Python 中是如何工作的?
- Zip 作为列表理解
- XML 到 csv(-like) 格式
尽管我仍然需要考虑一下实际发生的事情,但我现在有了更好的理解。所以我想要实现的是将 xml 文档转换为 csv。上面的最后一个链接非常接近我想要做的,但是我的源 xml 没有最一致的结构,这就是我碰壁的地方。这是我的源 xml 的一个例子(为了这个例子而简化了):
<?xml version="1.0" encoding="utf-8"?>
<root>
<child>
<Name>John</Name>
<Surname>Doe</Surname>
<Phone>123456</Phone>
<Phone>654321</Phone>
<Fax>111111</Fax>
</child>
<child>
<Name>Tom</Name>
<Surname>Cat</Surname>
<Phone>98765</Phone>
<Phone>56789</Phone>
<Phone>00000</Phone>
</child>
</root>
如您所见,我可以在<child>
. 此外,如果某个元素没有价值,它甚至不会存在(比如第二个<child>
没有<Fax>
)。
这是我目前拥有的代码:
data = etree.parse(open('test.xml')).findall(".//child")
tags = ('Name', 'Surname', 'Phone', 'Fax')
for child in data:
for a in zip(*[child.findall(x) for x in tags]):
print([x.text for x in a])
>> Result:
['John', 'Doe', '123456', '111111']
尽管这为我提供了一种可用于编写 csv 的格式,但它有两个问题:
它跳过第二个孩子,因为它没有
<Fax>
元素(我想)。如果我只通过设置搜索两个孩子中都存在的元素,tags = ('Name', 'Surname')
那么我有 2 个列表返回(太棒了!)第一个孩子实际上有 2 个电话号码,但只返回一个
从我可以测试的结果来看,当 zip* 发挥作用时,东西开始消失......我怎么能设置一个默认值以便我可以保留空值?
更新:为了更清楚我打算做什么,这是预期的输出格式(带分号分隔符的 CSV,其中每个字段中的多个值用逗号分隔):
John;Joe;123456,654321;111111;
Tom;Cat;98765,56789;00000;;
谢谢!