Safe Method to Get Value of Nested Dictionary

Safe method to get value of nested dictionary

You could use get twice:

example_dict.get('key1', {}).get('key2')

This will return None if either key1 or key2 does not exist.

Note that this could still raise an AttributeError if example_dict['key1'] exists but is not a dict (or a dict-like object with a get method). The try..except code you posted would raise a TypeError instead if example_dict['key1'] is unsubscriptable.

Another difference is that the try...except short-circuits immediately after the first missing key. The chain of get calls does not.


If you wish to preserve the syntax, example_dict['key1']['key2'] but do not want it to ever raise KeyErrors, then you could use the Hasher recipe:

class Hasher(dict):
# https://stackoverflow.com/a/3405143/190597
def __missing__(self, key):
value = self[key] = type(self)()
return value

example_dict = Hasher()
print(example_dict['key1'])
# {}
print(example_dict['key1']['key2'])
# {}
print(type(example_dict['key1']['key2']))
# <class '__main__.Hasher'>

Note that this returns an empty Hasher when a key is missing.

Since Hasher is a subclass of dict you can use a Hasher in much the same way you could use a dict. All the same methods and syntax is available, Hashers just treat missing keys differently.

You can convert a regular dict into a Hasher like this:

hasher = Hasher(example_dict)

and convert a Hasher to a regular dict just as easily:

regular_dict = dict(hasher)

Another alternative is to hide the ugliness in a helper function:

def safeget(dct, *keys):
for key in keys:
try:
dct = dct[key]
except KeyError:
return None
return dct

So the rest of your code can stay relatively readable:

safeget(example_dict, 'key1', 'key2')

How to get nested dictionary key value with .get()

dict.get accepts additional default parameter. The value is returned instead of None if there's no such key.

print myDict.get('key1', {}).get('attr3')

Accessing value inside nested dictionaries

You can use the get() on each dict. Make sure that you have added the None check for each access.

Extract fields in a dynamically nested dictionary in an ordered manner

def dict_value(val: dict):
for key, item in val.items():
if type(item) == dict:
dict_value(item)
else:
print(item)

dict_value(data)

how do I get keys from a nested dictionary?

Why don't just using pandas?

>>> import pandas as pd
>>> df = pd.DataFrame(mapSel["points"])
>>> df
curveNumber location pointIndex pointNumber z
0 0 Cascais 152 152 187.769
1 0 Oeiras 158 158 186.113
2 0 Sintra 159 159 221.223

If you just need locations, then you can just access that particular column.

>>> df["location"]
0 Cascais
1 Oeiras
2 Sintra
Name: location, dtype: object

Trying to get specific values from nested dictionary based on user input

This will solve your problem

usrnm = input("Enter username: ")
psw = input("Enter password: ")

found_flag = False
for ctmr in customer_dict:
u = customer_dict[ctmr].get("Username")
p = customer_dict[ctmr].get("Password")
if usrnm != u or psw != p:
continue
else:
found_flag = True
break

if found_flag == True:
print('Welcome')
else:
print('Wrong Credentials')

Python: Safe dictionary access with lists?

For dict you can use the get method. For lists you can just be careful with the index:

data.get('object_1', {}).get('object_2', {}).get('list', [{}])[0].get('property', default)

This is a bit awkward because it makes a new temporary dict or lost for each call get. It's also not super safe for lists, which don't have an equivalent method.

You can wrap the getter in a small routine to support lists too, but it's not really worth it. You're better off writing a one-off utility function that uses either exception handling or preliminary checking to handle the cases you want to react to:

def get(obj, *keys, default=None):
for key in keys:
try:
obj = obj[key]
except KeyError, IndexError:
return default
return obj

Exception handing has a couple of huge advantages over doing it the other way. For one thing, you don't have to do separate checks on the key depending on whether the object is a dict or list. For another, you can support almost any other reasonable type that supports __getitem__ indexing. To show what I mean, here is the asking for permission rather than forgiveness approach:

from collections.abc import Mapping, Sequence
from operator import index

def get(obj, *keys, default=None):
for key in keys:
if isinstance(obj, Mapping):
if key not in obj:
return default
elif isinstance(obj, Sequence):
try:
idx = index(key)
except TypeError:
return default
if len(obj) <= idx or len(obj) < -idx:
return default
obj = obj[key]
return obj

Observe how awkward and error-prone the checking is. Try passing in a custom object instead of a list, or a key that's not an integer. In Python, carefully used exceptions are your friend, and there's a reason it's pythonic to ask for forgiveness rather than for permission.

Get all keys of a nested dictionary

Here is code that would print all team members:

for k, v in Liverpool.items():
for k1, v1 in v.items():
print(k1)

So you just iterate every inner dictionary one by one and print values.

What method gets called when I change a value in a nested dictionary?

Calling this code:

tester["key2"]["subkey"] = "Added value"

is equivalent to the following two lines:

key2_value = tester["key2"]
key2_value["subkey"] = "Added value"

In the first line, PersistentStorage.__getitem__ is called (because tester is a PersistentStorage)

In the second line, dict.__setitem__ is called (because key2_value is a dict).

If you want to override that setter, you should not use a "normal" dict as tester["key2"].

You could, for example, change this line:

tester["key2"] = {"subkey":""}

to this:

tester["key2"] = MyDictWithOverridden_setitem({"subkey":""})

And then implement MyDictWithOverridden_setitem, or whatever you call it as e.g.

class MyDictWithOverridden_setitem(dict):
def __setitem__(self, key, value):
do_something_special()


Related Topics



Leave a reply



Submit