Reading specific key values from a dictionary of dictionary

329 Views Asked by At

I have a dictionary of dictionaries as follows:

dictofdict = {'001': {'date': 201504, 'status':'New'}, '002': {'date':201504, 'status':'Constant', 'rate':'-10'}, '003':{'date': 201504, 'status':'In Review'}}

The inner dictionaries may or may not have all the following keys: date, status and rate. For example: 001 and 003 do not have the key rate in their dictionary of values.

How do I read this dictionary of dictionaries such that I have an output as follows. I am interested in only the date and status keys from the inner dictionaries.

201504    001    New
201504    002    Constant
201504    003    In Review
2

There are 2 best solutions below

9
On BEST ANSWER

You can use an if clause to check if they exist in the inner dictionary

>>> for k,v in dictofdict.items():
...      if 'date' in v and 'status' in v:
...           print("{}\t{}\t{}".format(v['date'],k,v['status']))
... 
201504  003 In Review
201504  002 Constant
201504  001 New

If you are particular about the order then you will have to use sorted as a dictionary otherwise is un-ordered

>>> for k,v in sorted(dictofdict.items()):
...      if 'date' in v and 'status' in v:
...           print("{}\t{}\t{}".format(v['date'],k,v['status']))
... 
201504  001 New
201504  002 Constant
201504  003 In Review

As Padraic mentions you can use a list comprehension to store these values.

[(k, d["date"], d["status"]) for k, d in sorted(dictofdict.items()) if "date" in d and "status" in d]

This can be used as

>>> l = [(k, d["date"], d["status"]) for k, d in sorted(dictofdict.items()) if "date" in d and "status" in d]
>>> for i,j,k in l:
...     print("{}\t{}\t{}".format(i,j,k))
... 
201504  001 New
201504  002 Constant
201504  003 In Review

As JonCle mentions below

You can use set.issubset in your clause too.

This can be used as

>>> for k,v in sorted(dictofdict.items()):
...       if {'date', 'status'}.issubset(v):
...            print("{}\t{}\t{}".format(v['date'],k,v['status']))
... 
201504  001 New
201504  002 Constant
201504  003 In Review

One final approach is the EAFP. Called as Easier to ask for forgiveness than permission, you can avoid the if clause completely here!

>>> for k, v in sorted(dictofdict.items()):
...     try:
...         print '{date}\t{}\t{status}'.format(k, **v)
...     except KeyError:
...         pass
... 
201504  001 New
201504  002 Constant
201504  003 In Review

The working of this is that we assume that the key is present in the dict. If it is not there, an exception would be raised. Here we choose to ignore that as it is not required for us.

Note:

As you have a dictionary here, you can take advantage of the format method here to print the keys of the dictionary (You can see a few examples here) and supply the keys of the dictionary as fields in format

This can be done as

print('{date}\t{}\t{status}'.format(k, **v))
2
On

To do this, you need to check if inner dicts contain the key status and date. Also, to print in order, you can use the sorted() function.

>>> dictofdict = {'001': {'date': 201504, 'status':'New'}, '002': {'date':201504, 'status':'Constant', 'rate':-10}, '003':{'date': 201504, 'status':'In Review'}}

>>> for number in  sorted(dictofdict):
    # Only print if date and status key are present in the inner dict
    if 'date' in dictofdict[number] and 'status' in  dictofdict[number]:
        print '{}\t{}\t{}'.format(dictofdict[number]['date'], number, dictofdict[number]['status'])


201504  001 New
201504  002 Constant
201504  003 In Review