Access and modify deeply nested data structures using simple delimiter-separated paths.
No more chaining [] operators — just "a->b->0".
Python 3.8+ | Zero dependencies
Table of Contents
| Section | Description |
|---|---|
| Installation | How to install |
| Quick Start | Basic usage |
| Access Methods | get, [], dot notation, callable |
| Modification | set, []=, dot notation, callable |
| Options | Delimiters, defaults, modify flag |
| Classes | NestedDict, NestedList, NestedTuple |
| API Reference | Full method reference |
| Contributing | How to contribute |
pip install -U diginfrom digin import NestedDict
data = {
"users": {
"alice": {"age": 30, "hobbies": ["reading", "coding"]},
"bob": {"age": 25, "hobbies": ["gaming", "cooking"]}
}
}
nd = NestedDict(data)
# Read nested values
nd.get("users->alice->age") # 30
nd["users->bob->hobbies->0"] # 'gaming'
nd.users.alice.hobbies # NestedList(['reading', 'coding'])
# Modify nested values
nd.set("users->alice->age", 31)
nd["users->bob->hobbies->1"] = "hiking"
nd.users.bob.age = 26
nd("users->alice->hobbies->0", "writing") # set via callableget()
nd = NestedDict(data)
# String path with delimiter
nd.get("users->alice->age") # 30
# List/tuple of keys
nd.get(["users", "alice", "age"]) # 30
nd.get(("users", "alice", "hobbies", 0)) # 'reading'
# Integer key (for lists)
nl = NestedList([10, 20, 30])
nl.get(1) # 20
# Default value if not found
nd.get("users->charlie->age", default=0) # 0[] bracket notation
nd["users->alice->age"] # 30
nd[["users", "bob", "hobbies"]] # NestedList(['gaming', 'cooking'])Dot notation
nd.users.alice.age # 30
nd.users.bob.hobbies # NestedList(['gaming', 'cooking'])Note: dot notation only works with string keys that are valid Python identifiers.
Callable
# Get value
nd("users->alice->age") # 30
# Get with default
nd("users->charlie->age", default="N/A") # 'N/A'
# Set value (pass value as second argument)
nd("users->alice->age", 31) # sets age to 31set()
nd.set("users->alice->age", 31)
nd.set(["users", "bob", "age"], 26)[]= bracket assignment
nd["users->alice->age"] = 31
nd[["users", "bob", "age"]] = 26Dot notation assignment
nd.users.alice.age = 31
nd.users.bob.age = 26Callable assignment
nd("users->alice->age", 31)
nd("users->bob->hobbies->0", "swimming")Works with falsy values too — 0, "", False, [], {} are all valid:
nd("users->alice->active", False) # sets to False, not a get
nd("users->alice->score", 0) # sets to 0Custom Delimiter
Default delimiter is "->". Change it in the constructor:
nd = NestedDict(data, delimiter=".")
nd.get("users.alice.age") # 30
nd["users.bob.hobbies.0"] # 'gaming'
nd2 = NestedDict(data, delimiter="/")
nd2.get("users/alice/age") # 30Modify Flag
By default, get() wraps dicts/lists/tuples in Nested objects. Use modify=True to get the raw value:
# Returns NestedDict (wrapped)
nd.get("users->alice")
# NestedDict({'age': 30, 'hobbies': ['reading', 'coding']})
# Returns plain dict (raw)
nd.get("users->alice", modify=True)
# {'age': 30, 'hobbies': ['reading', 'coding']}NestedDict
Extends dict with nested path access. Supports all dict methods plus nested get/set:
from digin import NestedDict
nd = NestedDict({"a": {"b": {"c": 1}}})
nd.get("a->b->c") # 1
nd.keys() # dict_keys(['a'])
len(nd) # 1NestedList
Extends list with nested path access:
from digin import NestedList
nl = NestedList([{"name": "Alice"}, {"name": "Bob"}])
nl.get("0->name") # 'Alice'
nl[1] # {'name': 'Bob'}
len(nl) # 2NestedTuple
Extends tuple with nested path access (read-only):
from digin import NestedTuple
nt = NestedTuple(({"a": 1}, {"b": 2}))
nt.get("0->a") # 1
nt[0] # {'a': 1}Nested (base class)
| Method | Description |
|---|---|
__init__(data, delimiter="->") |
Wrap data with given delimiter |
.get(key, default, modify=False) |
Get value at key path |
.set(key, value) |
Set value at key path |
.parse(value, modify=False) |
Wrap value in Nested subclass |
(key) |
Get value (callable) |
(key, value) |
Set value (callable) |
[key] |
Get value (bracket) |
[key] = value |
Set value (bracket) |
.key |
Get value (dot notation) |
.key = value |
Set value (dot notation) |
Key formats
| Format | Example | Description |
|---|---|---|
| String | "a->b->0" |
Delimiter-separated path |
| List | ["a", "b", 0] |
List of keys |
| Tuple | ("a", "b", 0) |
Tuple of keys |
| Int | 0 |
Direct index |
| None | None |
Returns self |
See CONTRIBUTING.md for development setup, versioning guide, and how to submit changes.