Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the pythonic way to access nested dicts without NoneType errors

I have a deep nested dict (decoded from json, from the instagram api). My initial code was like this:

caption = post['caption']['text']

But that would throw a NoneType or KeyError error if the 'caption' key or the 'text' key doesn't exist.

So I came up with this:

caption = post.get('caption', {}).get("text")

Which works, but I'm not sure about the style of it. For instance, if I apply this technique to one of the deeper nested attributes I'm trying to retrieve, it looks pretty ugly:

image_url = post.get('images',{}).get('standard_resolution',{}).get('url')

Is there a better, more pythonic, way to write this? My goal is to retrieve the data, if it's there, but not to hold up execution if it's not there.

Thanks!

like image 783
Kenny Winker Avatar asked Dec 07 '22 09:12

Kenny Winker


2 Answers

The most Pythonic way would be simply to catch the KeyError:

try:
    caption = post['caption']['text']
except KeyError:
    caption = None

This is simple, obvious, and immediately understandable to a Python programmer.

like image 169
nneonneo Avatar answered Jan 10 '23 08:01

nneonneo


Python 3.4 and newer versions contains a contextlib context manager suppress, which is for exactly this kind of thing. Suppressing specific errors when you know in advance they may happen and your code can handle it.

from contextlib import suppress

sample = {'foo': 'bar'}

with suppress(KeyError):
    print(sample['baz'])

Will prevent the KeyError from being raised.

So for accessing getting a deeply nested dictionary value, you can use suppress like this.

value = None
with suppress(KeyError):
    value = data['deeply']['nested']['dictionary']['key']
like image 44
Techdragon Avatar answered Jan 10 '23 10:01

Techdragon