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 location
s, 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
Transpose Column to Row with Spark
Unnest (Explode) a Pandas Series
Python: Calling 'List' on a Map Object Twice
Python: Problem with Raw_Input Reading a Number
Regular Expression Matching a Multiline Block of Text
Typeerror: Unhashable Type: 'Dict'
How to Construct a Timedelta Object from a Simple String
How to Get the Input from the Tkinter Text Widget
How to Remove Non-Ascii Characters But Leave Periods and Spaces
Python: Access Class Property from String
Python Multiprocessing Linux Windows Difference
Is Shared Readonly Data Copied to Different Processes for Multiprocessing
Extract Text from Xml Documents in Python
How to Load All Entries in an Infinite Scroll at Once to Parse the HTML in Python