Skip to main content

PyPI version PyPI downloads PyPI pyversions PyPI license GitHub stars GitHub issues GitHub last commit

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)

Source distribution for digin 0.4.0
File Size Uploaded Provenance
digin-0.4.0.tar.gz 7.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for digin 0.4.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page