Last active
February 9, 2024 23:29
-
-
Save PatrikHlobil/9d045e43fe44df2d5fd8b570f9fd78cc to your computer and use it in GitHub Desktop.
Get all keys or values of a nested dictionary or list in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def iterate_all(iterable, returned="key"): | |
"""Returns an iterator that returns all keys or values | |
of a (nested) iterable. | |
Arguments: | |
- iterable: <list> or <dictionary> | |
- returned: <string> "key" or "value" | |
Returns: | |
- <iterator> | |
""" | |
if isinstance(iterable, dict): | |
for key, value in iterable.items(): | |
if returned == "key": | |
yield key | |
elif returned == "value": | |
if not (isinstance(value, dict) or isinstance(value, list)): | |
yield value | |
else: | |
raise ValueError("'returned' keyword only accepts 'key' or 'value'.") | |
for ret in iterate_all(value, returned=returned): | |
yield ret | |
elif isinstance(iterable, list): | |
for el in iterable: | |
for ret in iterate_all(el, returned=returned): | |
yield ret |
def get_keys(dictionary):
result = []
for key, value in dictionary.items():
if type(value) is dict:
new_keys = get_keys(value)
result.append(key)
for innerkey in new_keys:
result.append(f'{key}/{innerkey}')
else:
result.append(key)
return result
Very useful thanks!
I used @mh-malekpour code and added support for objects that are nested inside of arrays.
def generic_items(dict_or_list):
if type(dict_or_list) is dict:
return dict_or_list.items()
if type(dict_or_list) is list:
return enumerate(dict_or_list)
def get_keys(dictionary):
result = []
for key, value in generic_items(dictionary):
if type(value) is dict or type(value) is list:
new_keys = get_keys(value)
result.append(key)
for innerkey in new_keys:
result.append(f'{key}/{innerkey}')
else:
result.append(key)
return result
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First, great job! Thanks.
Then, a follow up question (of course):
Is it possible to modify the function so it returns keys (for example) while maintaining their hierarchy/order?
For example:
emps = {'emp1': {'name': 'Abe', 'position': {'office':'Mgr'},'home':'tenant'}, 'emp2': {'name': 'Bom', 'position': {'office':'Mgr'},'home':'tenant'}}
for i in iterate_all(emps): print(i)
returns:
emp1 name position office home emp2 name position office home
Can it return instead
emp1
emp1/name
emp1/position
emp1/position/office
emp1/position/home
emp2
emp2/name
emp2/position
emp2/position/office
emp2/position/home
Sometime the position of an element in the tree is important; that's why I'm asking.
Thanks.