digin
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 |
Installation
pip install -U digin
Quick Start
from 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 callable
Access Methods
get()
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 31
Modification
set()
nd.set("users->alice->age", 31)
nd.set(["users", "bob", "age"], 26)
[]= bracket assignment
nd["users->alice->age"] = 31
nd[["users", "bob", "age"]] = 26
Dot notation assignment
nd.users.alice.age = 31
nd.users.bob.age = 26
Callable 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 0
Options
Custom 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") # 30
Modify 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']}
Classes
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) # 1
NestedList
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) # 2
NestedTuple
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}
API Reference
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 |
Contributing
See CONTRIBUTING.md for development setup, versioning guide, and how to submit changes.
Metadata
Release files for digin 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| digin-0.4.0.tar.gz | 7.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| digin-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 14.2 kB
Release files / digin-0.4.0.tar.gz
| Download URL | digin-0.4.0.tar.gz |
|---|---|
| Size | 7.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8c477d726aa68af56e6b7c352fead07a2b78e1c8816782b3fc4de79a91c2575c
|
|
BLAKE2b-256 checksum How to use checksums |
c1994a3219c993a88533a0da7bcfcd1c26ade22c1926ebe61dde02f3a0851bdc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / digin-0.4.0-py3-none-any.whl
| Download URL | digin-0.4.0-py3-none-any.whl |
|---|---|
| Size | 6.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
044f03c6c606aedc5ddab127d732dbc5f544d98d6c8dc29c08fa590a8598481f
|
|
BLAKE2b-256 checksum How to use checksums |
da3e8dc40ecbae6bfb3f5eb6cd6df249af63ff5988067581ab07892f198f6107
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for digin 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.