Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

TinyTrie

A minimal and type-safe trie (prefix tree) implementation for Python 2+.

Features

  • Typed: Works with arbitrary key and value types (Generic[K, V])
  • Minimal: Only essential functionalities
  • Efficient: Memory-efficient with __slots__
  • Iterable: Easily traverse and list all stored sequences
  • No external dependencies (except typing on Python <3.5)

Basic Operations

from tinytrie import *

# Create a trie with character (`str`) keys and integer values
root = TrieNode[str, int]()

# Insert some words with values
update(root, 'apple', 1)
update(root, 'app', 2)
update(root, 'banana', 3)
update(root, 'band', 4)

# Search for existing words
assert search(root, 'apple').value == 1
assert search(root, 'app').value == 2
assert search(root, 'banana').value == 3

# Search for non-existent words
assert search(root, 'orange') is None
assert search(root, 'appetizer') is None

update(root, 'apple', 10)
assert search(root, 'apple').value == 10  # Value updated

# Insert a new word
update(root, 'orange', 5)
assert search(root, 'orange').value == 5

# Delete 'apple', 'app' remains
assert delete(root, 'apple') is True
assert search(root, 'apple') is None
assert delete(root, 'apple') is False
assert search(root, 'app') is not None

# Add back 'apple', delete 'app', 'apple' remains
update(root, 'apple', 10)
assert delete(root, 'app') is True
assert search(root, 'app') is None
assert delete(root, 'app') is False
assert search(root, 'apple') is not None

# Try to delete non-existent words
assert delete(root, 'ban') is False
assert delete(root, 'appetizer') is False

# Get common prefix from root (no common prefix)
prefix, _ = longest_common_prefix(root)
assert prefix == []  # No common prefix among all words

# Get common prefix from 'b' subtrie
subtrie_prefix = ['b']
b_subtrie_root = get_subtrie_root(root, subtrie_prefix)
prefix, _ = longest_common_prefix(b_subtrie_root)
assert prefix == ['a', 'n']  # Common between 'banana' and 'band' after 'b'

# Get all words in the trie
words = {''.join(s) for s, _ in collect_sequences(root)}
assert words == {'apple', 'banana', 'band', 'orange'}

# Get all words in the 'ba' subtrie
subtrie_prefix = ['b', 'a']
ba_subtrie_root = get_subtrie_root(root, subtrie_prefix)
words_starting_with_ba = {''.join(s) for s, _ in collect_sequences(ba_subtrie_root, prefix=subtrie_prefix)}
assert words_starting_with_ba == {'banana', 'band'}

Non-String Keys Example

from tinytrie import *

# Create a trie with tuple keys
trajectory_trie = TrieNode[Tuple[int, int], str]()
update(trajectory_trie, [(1, 2), (3, 4)], 'traj1')
update(trajectory_trie, [(1, 2), (5, 6)], 'traj2')

assert search(trajectory_trie, [(1, 2), (3, 4)]).value == 'traj1'
assert search(trajectory_trie, [(1, 2), (5, 6)]).value == 'traj2'
assert search(trajectory_trie, [(1, 2)]) is None  # Partial path

prefix, _ = longest_common_prefix(trajectory_trie)
assert prefix == [(1, 2)]

API Reference

Function Purpose Time Complexity
traverse(root: TrieNode[K, V], path: Iterable[K]) -> Iterator[Tuple[Optional[TrieNode[K, V]], K]] Yields nodes and keys along a path of keys (even if it diverges) O(n)
get_subtrie_root(root: TrieNode[K, V], path: Iterable[K]) -> Optional[TrieNode[K, V]] Gets the root node of a subtrie at the end of a path of keys if it exists O(n)
search(root: TrieNode[K, V], sequence: Iterable[K]) -> Optional[TrieNode[K, V]] Returns terminal node if sequence is stored in the trie O(n)
update(root: TrieNode[K, V], sequence: Iterable[K], value: Optional[V] = None) -> TrieNode[K, V] Inserts or updates a sequence and sets its value O(n)
delete(root: TrieNode[K, V], sequence: Sequence[K]) -> bool Removes a sequence and prunes dead nodes O(n)
longest_common_prefix(root: TrieNode[K, V]) -> Tuple[Sequence[K], TrieNode[K, V]] Finds the longest common prefix of all sequences and its terminal node O(m)
collect_sequences(root: TrieNode[K, V], prefix: Optional[List[K]] = None) -> Iterator[Tuple[List[K], TrieNode[K, V]]] Yields all stored sequences and their terminal nodes O(n) per sequence

Contributing

Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.

License

This project is licensed under the MIT License.

Release files for tinytrie 0.1.0a7

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

Source distribution (sdist)

Source distribution for tinytrie 0.1.0a7
File Size Uploaded
tinytrie-0.1.0a7.tar.gz 5.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tinytrie 0.1.0a7
File Interpreter ABI Platform
tinytrie-0.1.0a7-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 11.8 kB

Release files / tinytrie-0.1.0a7.tar.gz

Download URL tinytrie-0.1.0a7.tar.gz
Size 5.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8eedb53a1dcf904bd67a70cf95708aad592997646df902b444d3f6946c50bb83
BLAKE2b-256 checksum
How to use checksums
46b2e481d022d1e05a5d08f58bf3d75fdfe2258de333184e99ef066545510f3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release files / tinytrie-0.1.0a7-py2.py3-none-any.whl

Download URL tinytrie-0.1.0a7-py2.py3-none-any.whl
Size 6.1 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
7955d7ea9ab7bdb5c00a6c53ddbf046dd717d53a2342f772de898b25b2a829e0
BLAKE2b-256 checksum
How to use checksums
eed24b0a167f6e5b3717f0a55e1487b9c69a60bc52f13012644ecad027f4cd36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release history Release notifications | RSS feed

This release

0.1.0a7 This release

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