fluttersmith/py-snippetsGitHub ↗

Get a value from nested data

Follow a path of keys and indexes through nested dicts and lists, with a default.

Dicts#nested#searchO(k) time✓ 4 examples pass on 3.11–3.14

data['user']['posts'][0]['title'] raises somewhere in the middle when the JSON is missing a piece. This returns a default instead.

get_nested.py✓ ruff · mypy --strict
from collections.abc import Hashable, Iterable
from typing import Any


def get_nested(data: Any, path: Iterable[Hashable], default: Any = None) -> Any:
    """Follow ``path`` through nested dicts and lists, or return ``default``."""
    for step in path:
        try:
            data = data[step]
        except (KeyError, IndexError, TypeError):
            return default
    return data
  1. missing key, index out of range, or a step into a non-container
examples✓ 4 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> users = {"fred": {"name": {"last": "Smith"}, "posts": [1, 2, 3]}}passed on Python 3.11 to 3.14: >>> get_nested(users, ["fred", "name", "last"])'Smith'passed on Python 3.11 to 3.14: >>> get_nested(users, ["fred", "posts", 1])2passed on Python 3.11 to 3.14: >>> get_nested(users, ["fred", "posts", 9], default=0)0
Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).

How it works

  • Each step indexes into the current value.
  • A missing key, an index out of range, or indexing into None all return default.
  • Paths can mix dict keys and list indexes.

Complexity: O(k) time for a path of length k

Importfrom pysnippets.dicts.get_nested import get_nestedNo dependencies: copy get_nested.py into your project, or clone the repo.

Adapted from get in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Renamed from get; returns a default instead of raising; typed. Suggest an edit.