I have a Python object with multiple layers of dicts and lists that contain keys that I need to get the values from. I found an answer using recursive generators that will allow me to pull the value of one key, but not multiple keys. Here's the code:
with open('data.json') as f:
json_data = json.load(f)
def find_key(obj, key):
if isinstance(obj, dict):
yield from iter_dict(obj, key, [])
elif isinstance(obj, list):
yield from iter_list(obj, key, [])
def iter_dict(d, key, indices):
for k, v in d.items():
if k == key:
yield indices + [k], v
if isinstance(v, dict):
yield from iter_dict(v, key, indices + [k])
elif isinstance(v, list):
yield from iter_list(v, key, indices + [k])
def iter_list(seq, key, indices):
for k, v in enumerate(seq):
if isinstance(v, dict):
yield from iter_dict(v, key, indices + [k])
elif isinstance(v, list):
yield from iter_list(v, key, indices + [k])
for c in find_key(json_data, 'customer_count'):
print(c)
Result:
(['calendar', 'weeks', 0, 'days', 1, 'availabilities', 0, 'customer_count'], 14)
(['calendar', 'weeks', 0, 'days', 2, 'availabilities', 0, 'customer_count'], 7)
Another post has an example to extract multiple keys, but doesn't recurse through the entire object:
[...]
keys = ("customer_count", "utc_start_at", "non_resource_bookable_capacity")
for k in keys:
keypath, val = next(find_key(json_data, k))
print("{!r}: {!r}".format(k, val))
Result:
'customer_count': 14
'utc_start_at': '2018-09-29T16:45:00+0000'
'non_resource_bookable_capacity': 18
How do I iterate through the entire object and extract the three keys shown above?
My desired result would look something like this:
'customer_count': 14
'utc_start_at': '2018-09-29T16:45:00+0000'
'non_resource_bookable_capacity': 18
'customer_count': 7
'utc_start_at': '2018-09-29T16:45:00+0000'
'non_resource_bookable_capacity': 25