Using python generators for dictionaries

75 Views Asked by At

I have some xml data I want to organize into a dict with a generator, I only want the subContainers:

import xml.etree.ElementTree as Etree

xml_file = '\
<Container>\
    <Main Type="main1" var1="var1"/>\
    <SubContainer1>\
        <Sub Type="sub1" var1="var1" var2="var2"/>\
        <Sub Type="sub2" var1="var1" var2="var2"/>\
    </SubContainer1>\
    <SubContainer2>\
        <Var ObjectId="0000000001" Name="Name1" Value="1" />\
        <Var ObjectId="0000000001" Name="Name2" Value="2" />\
        <Var ObjectId="0000000001" Name="Name3" Value="3" />\
        <Var ObjectId="0000000001" Name="Name4" Value="4" />\
        <Var ObjectId="0000000001" Name="Name5" Value="5" />\
        <Var ObjectId="0000000001" Name="Name6" Value="6" />\
    </SubContainer2>\
</Container>'

xml_tree = Etree.fromstring(xml_file)
xml_dict = {}

sub_containers = ['SubContainer1','SubContainer2']
for c in sub_containers:
    xml_dict[c] = [{x.tag : x.attrib} for x in xml_tree.findall(f'.//{c}/*')]

print(xml_dict)

Unfortunately the generator gives me a list like so:

{'SubContainer1': [{'Sub': {'Type': 'sub1', 'var1': 'var1', 'var2': 'var2'}}, {'Sub': {'Type': 'sub2', 'var1': 'var1', 'var2': 'var2'}}], 'SubContainer2': [{'Var': {'ObjectId': '0000000001', 'Name': 'Name1', 'Value': '1'}}, {'Var': {'ObjectId': '0000000001', 'Name': 'Name2', 'Value': '2'}}, {'Var': {'ObjectId': '0000000001', 'Name': 'Name3', 'Value': '3'}}, {'Var': {'ObjectId': '0000000001', 'Name': 'Name4', 'Value': '4'}}, {'Var': {'ObjectId': '0000000001', 'Name': 'Name5', 'Value': '5'}}, {'Var': {'ObjectId': '0000000001', 'Name': 'Name6', 'Value': '6'}}]}

I have to access the dict clunky like this: xml_dict['SubContainer1'][0] The [0] can surely be avoided somehow, but Im too unexperienced. Can you help me with constructing a proper dict from the xml?

1

There are 1 best solutions below

0
Woodford On

You're assigning a list to each subcontainer key. It's not clear exactly what structure you're looking for but eliminating the list (and the associated [0]) is pretty straightforward:

for c in sub_containers:
   xml_dict[c] = {x.tag : x.attrib for x in xml_tree.findall(f'.//{c}/*')}