How to find if multi-level key exists in dict?

I’m using Python 3.9 on Windows for the sake of a tutorial.

I’m reading an XML file by using xmltodict. It produces a dictionary with nested keys. I would like to see if the key exists before I assign the value of the element to a variable. I have read about 6 web pages and all the examples only show single-level non-nested keys in a dict.

I have tried these methods. The commented code are other methods I tried and didn’t work for some reason.

        if xmldict.get(('something', 'else')):
            bad = xmldict.get('something','')
        # if xmldict['something']:  # Gives KeyError
        #     bad = xmldict['something']
        # try:
        #     bad = xmldict['something']
        # except:
        #     bad=''

I also tried this, with a key that does exist. This came from the actual Python docs.

if ['Order']['OrderHeader']['Orderid'] in xmldict:
    orderid = xmldict['Order']['OrderHeader']['OrderID']

Some methods gave a KeyError. Some didn’t get the data even if the key was in the XML file.

  1. How do I check if the multi-level key exists before I assign the XML contents to a variable?
  2. Alternately, how do I get the contents of an XML element using xmltodict, without seeing a console error if the data does not exist?

That’s strange as, as far I know Python language, this is not a correct Python construct :astonished:

Python has got no language construct to test for multi-level key existence. However, you can write a function for it! Like this:

def has_ml_key(tested_object, *keys):
   for key in keys:
      if key in tested_object:
         tested_object = tested_object[key]
         return False
   return True

and use it like this:

if has_ml_key(xmldict, "Order", "OrderHeader", "OrderId"):
   #do stuff

Like this, maybe?

At some point I should write up something general about working with nested (JSON-like) data structures. But it’s hard to figure out the scope for something like that.

If that appears in any kind of documentation, I suspect it was meant as pseudocode. It is syntactically valid, but the lefthand side is an expression that would need to be evalauted, and ['Order']['OrderHeader'] is an attempt to index the list ['Order'] with a str value OrderHeader, which isn’t something the list type supports.

1 Like

Thank you! Your function works. I tested it with 3 levels (3 keys) and 4 levels (4 keys) deep in the XML file.