Skip to content

Instantly share code, notes, and snippets.

@toddbirchard
Last active September 6, 2023 04:40
Show Gist options
  • Star 42 You must be signed in to star a gist
  • Fork 18 You must be signed in to fork a gist
  • Save toddbirchard/b6f86f03f6cf4fc9492ad4349ee7ff8b to your computer and use it in GitHub Desktop.
Save toddbirchard/b6f86f03f6cf4fc9492ad4349ee7ff8b to your computer and use it in GitHub Desktop.
"""Extract nested values from a JSON tree."""
def json_extract(obj, key):
"""Recursively fetch values from nested JSON."""
arr = []
def extract(obj, arr, key):
"""Recursively search for values of key in JSON tree."""
if isinstance(obj, dict):
for k, v in obj.items():
if isinstance(v, (dict, list)):
extract(v, arr, key)
elif k == key:
arr.append(v)
elif isinstance(obj, list):
for item in obj:
extract(item, arr, key)
return arr
values = extract(obj, arr, key)
return values
@lsaiken
Copy link

lsaiken commented Sep 10, 2020

Why not return arr from json_extract and remove returning it from extract since lists are mutable?

@selfcontrol7
Copy link

Awsome code. Thank's a lot, you save me hours of coding!!!!

@mark2m60
Copy link

mark2m60 commented Dec 3, 2021

This was great. Saved ton of time. Was able to modify an return 3 fields from 1 obj. Thank you!

@selfcontrol7
Copy link

Hello @Fjurg .
Thank you for your work. Your code works like a charm

@gstewart86
Copy link

Super useful function, thanks all. Here's @Fjurg 's code with added type hinting and more explicit parameter names

 from typing import Dict, List, Union, Any


def extract_values(object_to_search: Union[Dict[Any, Any], List[Any]], search_key: str) -> List:
    """Recursively pull values of specified key from nested JSON."""
    results_array: List = []

    def extract(object_to_search: Union[Dict[Any, Any], List[Any]], results_array: List[Any], search_key: str) -> List:
        """Return all matching values in an object."""
        if isinstance(object_to_search, dict):
            for key, val in object_to_search.items():
                if isinstance(val, (dict, list)):
                    if key == search_key:
                        results_array.append(val)
                    extract(val, results_array, search_key)
                elif key == search_key:
                    results_array.append(val)
        elif isinstance(object_to_search, list):
            for item in object_to_search:
                extract(item, results_array, search_key)
        return results_array

    results = extract(object_to_search, results_array, search_key)
    to_return = []
    for result in results:
        if type(result) == list:
            for item in result:
                to_return.append(item)
        else:
            to_return.append(result)
    return to_return

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment