More Than Five
More Than Five

Reputation: 10419

Pull a specific value from a specific Dict in a List of Dict's

I have a list of dict's...

categories = [{'summarycategory': {'amount':1233}},
             {'hhCategory': {}},
             {'information': {'mRoles': ['4456'],
                              'cRoles': None,
                              'emcRoles': ['spm/4456']}}]

I want to get value information.emcRoles. To do this, I do:

for x in categories:
    for key in x:
        if key == "information":
            print(x[key]["emcRoles"])

There must be a more pythonic way? Also, need it needs to be null safe. So if, "information" is not there, I don't want a null pointer looking for emcRoles.

Upvotes: 0

Views: 72

Answers (4)

chris
chris

Reputation: 1322

Depending on what else you're doing with your categories list it might make sense to convert your list of dictionaries to new dictionary:

newdictionary=dict([(key,d[key]) for d in categories for key in d])
print(newdictionary['information']['emcRoles'])

See how to convert list of dict to dict for more.

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

don't loop on the keys, you're killing the use of the dict key lookup (plain loop is O(n), dict lookup is O(1)

Instead, just check if key belongs, and go get it if it does.

for x in categories:
    if "information" in x:
        print(x["information"]["emcRoles"])

or use dict.get to save a dict key access:

for x in categories:
    d = x.get("information")
    if d is not None:   # "if d:" would work as well here
        print(d["emcRoles"])

to create a list of those infos instead, use a listcomp with a condition (again, listcomp makes it difficult to avoid the double dict key access):

[x["information"]["emcRoles"] for x in categories if "information" in x]

Upvotes: 3

llllllllll
llllllllll

Reputation: 16404

A one-liner:

next(x for x in categories if 'information' in x)['information']['emcRoles']

Upvotes: 2

Mike Scotty
Mike Scotty

Reputation: 10782

If information or emcRoles might be missing, you can either "ask for forgiveness", by wrapping it all in a try..except

try:
    for x in categories:
        if "information" in x:
            print(x["information"]["emcRoles"])
except:
    # handle gracefully ...

or you could use get() and provide fallback values as you see fit:

for x in categories:
    print(x.get("information", {}).get("emcRoles", "fallback_value"))

Upvotes: 1

Related Questions