Skip to main content

pure_radix

Radix tree library but in pure clean Python. Run it on PyPy or IronPython or wherever.

Dependencies

We try to keep dependencies light:

  • attrs dataclass library (2881 LoC)

To run the tests, you'll need pytest and optionally hypothesis.

Examples

>>> from pure_radix import SetNode
>>>
>>> # Create a tree where each node holds a set. You are free to
>>> # customize what information is held inside each node.
>>> t = SetNode()
>>>
>>> node1 = t.node_get((10, 11, 12), create=True)
>>> node2 = t.node_force((10, 11, 30))  # equivalent
>>>
>>> node1.add("cat")
>>> node2.add("dog")
>>>
>>> print(t.node_debug_string())
[]
  [10, 11]
    [30] {'dog'}
    [12] {'cat'}
>>>
>>> # This node exists because it's a common prefix between node1 and node2.
>>> t.node_get((10, 11))
SetNode(raw_data=None)
>>>
>>> # This node doesn't exist.
>>> print(t.node_get((10,)))
None

The library works with any kind of sequence, including strings!

>>> # It also works with strings!
>>> t = SetNode()
>>>
>>> t.node_force("catalogue").add(1)
>>> t.node_force("category").add(2)
>>> t.node_force("categorization").add(3)
>>> t.node_force("cart").add(4)
>>> t.node_force("carpet")  # leaf node without actual data!
SetNode(raw_data=None)
>>> t.node_force("car").add(5)
>>> t.node_force("star").add(6)
>>>
>>> print(t.node_debug_string())
[]
  ['c', 'a']
    ['t']
      ['a', 'l', 'o', 'g', 'u', 'e'] {1}
      ['e', 'g', 'o', 'r']
        ['i', 'z', 'a', 't', 'i', 'o', 'n'] {3}
        ['y'] {2}
    ['r'] {5}
      ['p', 'e', 't']
      ['t'] {4}
  ['s', 't', 'a', 'r'] {6}

Are you looking for the longest common prefix? Here is how you can get the nodes that have the longest common prefix with a sequence:

>>> for n, node in t.node_find_closest_nodes("catenary"):
...     print(n, node)
... 
4 SetNode(raw_data=None)
3 SetNode(raw_data={1})
2 SetNode(raw_data={5})
0 SetNode(raw_data={6})

Do you need to recursively get all non-empty nodes under a node?

>>> list(t.node_get("cat").node_find())
[SetNode(raw_data={2}), SetNode(raw_data={3}), SetNode(raw_data={1})]

Let's empty some nodes now!

>>> t.node_get("category").clear()
>>> t.node_get("catalogue").clear()
>>> t.node_get("star").clear()
>>> print(t.node_debug_string())
[]
  ['c', 'a']
    ['t']
      ['a', 'l', 'o', 'g', 'u', 'e']
      ['e', 'g', 'o', 'r']
        ['i', 'z', 'a', 't', 'i', 'o', 'n'] {3}
        ['y']
    ['r'] {5}
      ['p', 'e', 't']
      ['t'] {4}
  ['s', 't', 'a', 'r']

Empty nodes do not get removed automatically! You must remove them yourself:

>>> t.node_prune()
>>> print(t.node_debug_string())
[]
  ['c', 'a']
    ['r'] {5}
      ['t'] {4}
    ['t', 'e', 'g', 'o', 'r', 'i', 'z', 'a', 't', 'i', 'o', 'n'] {3}

Use a powerful method of traversal:

>>> def _enter(stack, frame):
...     yield ("enter", frame.node, frame.node.node_sequence)
...
>>> def _exit(stack, frame):
...     yield ("exit", frame.node, frame.node.node_sequence)
...
>>> for action, node, seq in t.node_visit(enter=_enter, exit=_exit):
...     print(action, node, seq)
enter SetNode(raw_data=None) ()
enter SetNode(raw_data=None) ('c', 'a')
enter SetNode(raw_data={5}) ('c', 'a', 'r')
enter SetNode(raw_data={4}) ('c', 'a', 'r', 't')
exit SetNode(raw_data={4}) ('c', 'a', 'r', 't')
exit SetNode(raw_data={5}) ('c', 'a', 'r')
enter SetNode(raw_data={3}) ('c', 'a', 't', 'e', 'g', 'o', 'r', 'i', 'z', 'a', 't', 'i', 'o', 'n')
exit SetNode(raw_data={3}) ('c', 'a', 't', 'e', 'g', 'o', 'r', 'i', 'z', 'a', 't', 'i', 'o', 'n')
exit SetNode(raw_data=None) ('c', 'a')
exit SetNode(raw_data=None) ()

Metadata

Release files for pure-radix 2.1.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 pure-radix 2.1.1
File Size Uploaded Provenance Actions
pure_radix-2.1.1.tar.gz 15.9 kB Without provenance Details for pure_radix-2.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pure-radix 2.1.1
File Interpreter ABI Platform Actions
pure_radix-2.1.1-py3-none-any.whl Python 3 none any Details for pure_radix-2.1.1-py3-none-any.whl

Total release size: 23.3 kB

Release files / pure_radix-2.1.1.tar.gz

Download URL pure_radix-2.1.1.tar.gz
Size 15.9 kB
Tags Source
SHA-256 checksum
How to use checksums
5cbc5fb1aca0be796ad1b67154642e78869a792b125f16e9dd1a18193f42d053
BLAKE2b-256 checksum
How to use checksums
a23e83c6a18b31a04c677f0a2017d00bc96f629bed02d7821552e7da3f45d899
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Release files / pure_radix-2.1.1-py3-none-any.whl

Download URL pure_radix-2.1.1-py3-none-any.whl
Size 7.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e2fd8e0f26096ece5934aa4f17b2f3728fdbd401282e81401015b9f4c2d94b2
BLAKE2b-256 checksum
How to use checksums
ad8a063ac826d198449c70a95e6f24471bb95a8be2ce6d995bbcdd910b4c6848
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.5

Security for pure-radix 2.1.1

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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