What is the proper way to extract the value from nested dictionary in Python?
Question:
A nested dictionary:
nested_dict = {"fruit": {"apple":{"status": "new", "sold": True},
"banana": 10,
"watermelon": 30},
"meat": {"red": 39, "white": 13}}
res = nested_dict.get("fruit", {}).get("apple", {}).get("status")
if res:
print(f"{res = }")
Is there any better practise to extract the value from the nested dictionary?
Answers:
I’m not totally sure about speed, but personally I like to reference dictionary elements in the same way you would access the elements of a list, tuple, or most other python data structure, like this for your example:
In [24]: res = nested_dict["fruit"]["apple"]["status"]
In [25]: print(res)
new
I should also note it looks like you’re constructing something known as a JSON file, a common file format which Python has a nice module for, i.e the json module. Might be worth looking into!
The proposal in your question is fine.
If you have a lot of data like this, it maybe worth writting some helper codem to avoid repetition, or install a 3rdy party lib that makes it easier to deal with nested data.
One such library is a project I authored named "extradict" (it can be installed with pip install extradict
). It features a NestedData
class which may hold nested dictionaries and lists, and allow for item access using the dot notation in the key. So you can get to your data, in this example, by using simply ["fruit.apple.status"]
. Here is the full snippet:
In [1]: nested_dict = {"fruit": {"apple":{"status": "new", "sold": True},
...: "banana": 10,
...: "watermelon": 30},
...: "meat": {"red": 39, "white": 13}}
In [2]: from extradict import NestedData
In [3]: nested = NestedData(nested_dict)
In [4]: nested.get("fruit.apple.status")
Out[4]: 'new'
In [5]: nested.get("fruit.mango.status")
<None>
In [7]:
Note however, that in this particular example, you will get an error with extradict.NestedData
if you try to get the "status" of a fruit that contains a number, and not another dict, which might contain the status key. Hopefully this is just example data, and you don’t have such heterogeneous data structures around.
In [7]: nested_dict.get("fruit", {}).get("banana", {}).get("status")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
(...)
AttributeError: 'int' object has no attribute 'get'
In [8]: nested.get("fruit.banana.status")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
(...)
TypeError: 'int' object is not subscriptable
A nested dictionary:
nested_dict = {"fruit": {"apple":{"status": "new", "sold": True},
"banana": 10,
"watermelon": 30},
"meat": {"red": 39, "white": 13}}
res = nested_dict.get("fruit", {}).get("apple", {}).get("status")
if res:
print(f"{res = }")
Is there any better practise to extract the value from the nested dictionary?
I’m not totally sure about speed, but personally I like to reference dictionary elements in the same way you would access the elements of a list, tuple, or most other python data structure, like this for your example:
In [24]: res = nested_dict["fruit"]["apple"]["status"]
In [25]: print(res)
new
I should also note it looks like you’re constructing something known as a JSON file, a common file format which Python has a nice module for, i.e the json module. Might be worth looking into!
The proposal in your question is fine.
If you have a lot of data like this, it maybe worth writting some helper codem to avoid repetition, or install a 3rdy party lib that makes it easier to deal with nested data.
One such library is a project I authored named "extradict" (it can be installed with pip install extradict
). It features a NestedData
class which may hold nested dictionaries and lists, and allow for item access using the dot notation in the key. So you can get to your data, in this example, by using simply ["fruit.apple.status"]
. Here is the full snippet:
In [1]: nested_dict = {"fruit": {"apple":{"status": "new", "sold": True},
...: "banana": 10,
...: "watermelon": 30},
...: "meat": {"red": 39, "white": 13}}
In [2]: from extradict import NestedData
In [3]: nested = NestedData(nested_dict)
In [4]: nested.get("fruit.apple.status")
Out[4]: 'new'
In [5]: nested.get("fruit.mango.status")
<None>
In [7]:
Note however, that in this particular example, you will get an error with extradict.NestedData
if you try to get the "status" of a fruit that contains a number, and not another dict, which might contain the status key. Hopefully this is just example data, and you don’t have such heterogeneous data structures around.
In [7]: nested_dict.get("fruit", {}).get("banana", {}).get("status")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
(...)
AttributeError: 'int' object has no attribute 'get'
In [8]: nested.get("fruit.banana.status")
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
(...)
TypeError: 'int' object is not subscriptable