Skip to main content

dict-traverser

Simple wrapper to work with deeply nested Python dictionaries and lists using dot-notation paths.

It supports safe lookups, nested updates, automatic structure creation, array indexing, and key deletion, ideal for working with JSON-like data structures.

Installation

pip install dict-traverser

Usage

DictTraverser

from dict_traverser import DictTraverser

data = {
    'user': {
        'profile': {
            'name': 'Alice',
            'emails': ['first@example.com', 'second@example.com'],
        },
    },
}

tv = DictTraverser(data)

# Get values
print(tv['user.profile.name'])  # 'Alice'
print(tv.get('user.profile.age', 30))  # 30 (default)
print(tv['user.profile.emails.[0]']) # first@example.com
print(tv['user.profile.emails.[-1]']) # second@example.com

# Set values (automatically creates the necessary structures)
tv['user.profile.age'] = 25
tv['user.profile.emails.[2]'] = 'third@example.com'

# Delete values
del tv['user.profile.name']

# Update with another dict
tv.update({
    'user': {'profile': {'country': 'US'}},
})

# Access the underlying dictionary
print(tv.obj)

# Resulting dictionary after the updates above
{
    'user': {
        'profile': {
            # Name got deleted
            'emails': [
                'first@example.com',
                'second@example.com',
                'third@example.com', # Added to the array
            ],
            'age': 25, # Added by setting the key
            'country': 'US', # Added by update() call
        },
    },
}

DictTraverser with custom separator

If the keys in your data include dots (.), you can provide a custom separator to DictTraverser:

from dict_traverser import DictTraverser

data = {
    'user': {
        'settings': {
            'theme': 'dark',
            'device.type': 'mobile',
        },
    },
}
tv = DictTraverser(data, '.')  # '.' is the default

try:
    tv['user.settings.device.type']
except KeyError:
    # Will raise KeyError because it tried to access a
    # dictionary called `api` inside `settings`
    pass

tv = DictTraverser(data, '+')  # Now use + signs for separators
print(tv['user+settings+theme'])  # dark

tv.separator = '|'  # You can also change the separator after creation
print(tv['user|settings|device.type'])  # mobile

unwind

Utility function to convert a nested dictionary to a one-level-deep dictionary with dot-notation keys

from dict_traverser import unwind

data = {
    'user': {
        'profile': {
            'name': 'Alice',
            'emails': ['first@example.com', 'second@example.com'],
        },
    },
}
print(unwind(data))
{
    'user.profile.name': 'Alice',
    'user.profile.emails': ['first@example.com', 'second@example.com'],
}

print(unwind(data, separator='|'))
{
    'user|profile|name': 'Alice',
    'user|profile|emails': ['first@example.com', 'second@example.com'],
}

print(unwind(data, initial_key='prefix'))
{
    'prefix.user.profile.name': 'Alice',
    'prefix.user.profile.emails': ['first@example.com', 'second@example.com'],
}

Metadata

Release files for dict-traverser 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dict-traverser 1.0.1
File Size Uploaded
dict_traverser-1.0.1.tar.gz 5.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dict-traverser 1.0.1
File Interpreter ABI Platform
dict_traverser-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 10.0 kB

Release files / dict_traverser-1.0.1.tar.gz

Download URL dict_traverser-1.0.1.tar.gz
Size 5.3 kB
Tags Source
SHA-256 checksum
How to use checksums
fa937c16e929168f32defb8526a1a798ead739426b3a826d987965d7d60cbe9c
BLAKE2b-256 checksum
How to use checksums
6704d3d2cd25083bbba32662b1e7fff63faf068160241f4c43ab4973d156049e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2025.

Transparency log

Release files / dict_traverser-1.0.1-py3-none-any.whl

Download URL dict_traverser-1.0.1-py3-none-any.whl
Size 4.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a834fda7b6067a08e2d7e770289930f89f9db32e8d8c206c15a5feb901b7fa6
BLAKE2b-256 checksum
How to use checksums
69e792836b1b0774659751bf7e5aab8756b6c4be6d9bbd2700244c6072ee2687
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

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