Papouche Guinslyzinho
Papouche Guinslyzinho

Reputation: 5458

How to iterate over an OrderedDict in an OrderedDict

Hi I would like to parse some order_dicts. I have this following error

ipdb> for elem in my_orderdict['codeBook'].keys():
          print("{0}  ===> {1}".format(elem, my_orderdict[elem ]))
*** KeyError: '@xmlns'

So let's say that I create an Orderdict that I would like to iterate over later to get each items and values.

ipdb >>> from collections import *
ipdb >>> my_orderdict = \
OrderedDict([('codeBook',
    OrderedDict([('@xmlns', 'http://www.johndoe.com'),
         ('@xmlns:xsi',
          'http://www.w3.org/2001/XMLSchema-instance'),
         ('@version', '1.2.2'),
         ('@ID', '_71M0001XCB-F-1991-novembre'),
         ('@xml-lang', 'en'),
         ('@xsi:schemaLocation', 'http://www.johndoe.xsd'),
         ('stdyDscr',
          OrderedDict([('stdyInfo',
              OrderedDict([('subject',
                  OrderedDict([('keyword',
                                ['Chômage',
                                 'Emploi'])]))]))]))]))])

ipdb >>> type(my_orderdict)
<class 'collections.OrderedDict'>

ipdb >>>  my_orderdict['codeBook'].keys()
odict_keys(['@xmlns', '@xmlns:xsi', '@version', 
            '@ID', '@xml-lang', '@xsi:schemaLocation', 'stdyDscr'])

I am creating a loop to access the value of each odict_keys

for elem in my_orderdict['codeBook'].keys():
    print("{0}  ===> {1}".format(elem, my_orderdict[elem ]))

The result that I would like should be

@xmlns ===> 'http://www.johndoe.com'
@xmlns:xsi ===> 'http://www.w3.org/2001/XMLSchema-instance'
@version ===> 1.2.2
...

so that I could parse this orderdict. Right now my errors is :

ipdb> for elem in my_orderdict['codeBook'].keys():
          print("{0}  ===> {1}".format(elem, my_orderdict[elem ]))
*** KeyError: '@xmlns'

So I can't access the attribute of my first orderdict.

Upvotes: 2

Views: 2633

Answers (2)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96172

You are iterating over the subdict's keys: for elem in my_orderdict['codeBook'].keys(): but then using those keys on the parent-dict: my_orderdict[elem ] you need to use my_orderdict['codeBook'], so:

In [2]: data = OrderedDict([('codeBook',
   ...:     OrderedDict([('@xmlns', 'http://www.johndoe.com'),
   ...:          ('@xmlns:xsi',
   ...:           'http://www.w3.org/2001/XMLSchema-instance'),
   ...:          ('@version', '1.2.2'),
   ...:          ('@ID', '_71M0001XCB-F-1991-novembre'),
   ...:          ('@xml-lang', 'en'),
   ...:          ('@xsi:schemaLocation', 'http://www.johndoe.xsd'),
   ...:          ('stdyDscr',
   ...:           OrderedDict([('stdyInfo',
   ...:               OrderedDict([('subject',
   ...:                   OrderedDict([('keyword',
   ...:                                 ['Chômage',
   ...:                                  'Emploi'])]))]))]))]))])

In [3]: for elem in data['codeBook']: #note, call to .keys is not necessary
   ...:     print("{0} ===> {1}".format(elem, data['codeBook'][elem]))
   ...:
@xmlns ===> http://www.johndoe.com
@xmlns:xsi ===> http://www.w3.org/2001/XMLSchema-instance
@version ===> 1.2.2
@ID ===> _71M0001XCB-F-1991-novembre
@xml-lang ===> en
@xsi:schemaLocation ===> http://www.johndoe.xsd
stdyDscr ===> OrderedDict([('stdyInfo', OrderedDict([('subject', OrderedDict([('keyword', ['Chômage', 'Emploi'])]))]))])

However, in this case, you can just use items, which iterates over key-value pairs:

In [4]: for k, v  in data['codeBook'].items():
   ...:     print("{0} ===> {1}".format(k, v))
   ...:
@xmlns ===> http://www.johndoe.com
@xmlns:xsi ===> http://www.w3.org/2001/XMLSchema-instance
@version ===> 1.2.2
@ID ===> _71M0001XCB-F-1991-novembre
@xml-lang ===> en
@xsi:schemaLocation ===> http://www.johndoe.xsd
stdyDscr ===> OrderedDict([('stdyInfo', OrderedDict([('subject', OrderedDict([('keyword', ['Chômage', 'Emploi'])]))]))])

Upvotes: 2

looks like your loop is not accessing the right dictionary. You should be using:

for elem in my_orderdict['codeBook'].keys():
    print("{0}  ===> {1}".format(elem, my_orderdict['codeBook'][elem ]))

Note the my_orderdict['codeBook'] in the inside loop.

Basically: you are iterating on the elements of the dictionary my_orderdict['codeBook'], but trying to access the values of my_orderdict directly.

Hope this helps!

Upvotes: 2

Related Questions