I wrote a function navigateDict
that does a safe navigation on a dict
, similar to dict.get()
but nested. It replaces code like
if 1 in data and 'i' in data[1] and 'a' in data[1]['i']:
print data[1]['i']['a']
else:
print "Not found"
with the roughly equivalent
found = navigateDict(data, 1, 'i', 'a')
if found is not None:
print found
else:
print "Not found"
The implementation is as follows:
# Allow fallback value other than None
def navigateDictEx(d, keys, fallback=None):
for key in keys:
if key in d:
d = d[key]
else:
return fallback
return d
def navigateDict(d, *keys):
return navigateDictEx(d, keys)
See the summary for example usage.
Pythonic or not, this function reduces repetition in a place where redundancy is a bad idea. For example, changing one path component in the example requires up to three distinct values to be modified as one in the original example, but only one in the modified example. Given my regular tendency to err, this is a big win.
Ultimately I'm asking this: Is there something in the standard library that does this, or am I going to need to find a place for it in my project's library?
brionius correctly points out that catching KeyError
will work:
try:
print data[1]['i']['a']
except KeyError:
print "Not found"
This might be the way I go; it's pretty terse and cuts the repetition. However, it does reflect an assumption that there will be more hits than misses. If there's a better way of assuming the opposite I'd like to know that, also.
tl;dr. With CPython 2.7, using dict() to create dictionaries takes up to 6 times longer and involves more memory allocation operations than the literal syntax. Use {} to create dictionaries, especially if you are pre-populating them, unless the literal syntax does not work for your case.
It's a dictionary subclass specially designed to remember the order of items, which is defined by the insertion order of keys. This changed in Python 3.6. The built-in dict class now keeps its items ordered as well.
Definition and Usage The dict() function creates a dictionary. A dictionary is a collection which is unordered, changeable and indexed.
One way to do this is as follows:
try:
print data[1]['i']['a']
except KeyError:
print "Not found!"
It's in line with the spirit of duck-typing. It may or may not be as fast, as I believe handling exceptions carries a certain amount of overhead, but it's certainly "safe".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With