Skip to content

Repository files navigation

itrx: A Chainable Iterable Adaptor

PyPI - Version PyPI - Python Version PyPI - License

itrx is a Python library that adapts iterators, iterables, and generators, providing a Rust-inspired Iterator trait experience with added Pythonic conveniences. It enables developers to build complex data processing pipelines with a fluent, chainable, and lazy API. In most cases, it simply wraps itertools and/or builtins in syntactic sugar.

Heavily inspired by Rust's Iterator trait, itrx offers a familiar and robust pattern for sequence manipulation.

Key Features & Why Itr?

  • Compatibility: Itr is designed to work seamlessly with various Python iterable types, including sequences, ranges, custom iterators, and generators.
  • Fluent & Chainable API: Write expressive, left-to-right sequences of operations on your data.
  • Lazy Evaluation: Operations are only performed when their results are needed, improving efficiency for large or infinite sequences.
  • Rust-Inspired Patterns: Bring the power and clarity of Rust's Iterator design to your Python projects.
  • Pythonic Additions: Includes convenient methods like starmap that integrate smoothly with Python's ecosystem.
  • Simplifies Complex Logic: Often provides a more readable and concise alternative to nested itertools or built-in functions.

Installation

pip install itrx

Using an AI coding agent? itrx ships an installable agent skill — run uv run itrx-skill --install and your agent gets a built-in reference for writing Itr chains correctly, without needing this whole README in context.

Quick Start & Core Functionality

Chaining

Itr wraps Python Iterators, Iterables, and Generators, allowing efficient chaining methods for data transformation. In this completely arbitrary example we take some integers, reverse them, discard some, take every 4th value and print it if its square ends with the digit 9:

>>> from itrx import Itr
>>> Itr(range(100)).rev().step_by(4).skip(10).map(lambda x: x * x).filter(lambda x: x % 10 == 9).for_each(print)
2209
1849
729
529
49
9

For reference, the equivalent expression using built-ins and itertools can be significantly less readable:

from itertools import islice

for item in filter(
    lambda x: x % 10 == 9,
    map(lambda x: x * x, islice(islice(reversed(range(100)), None, None, 4), 10, None)),
):
    print(item)

Outputs

While Itr methods typically return self or another Itr instance, the collect() method allows you to materialize the results into various Python collections: tuple (default), list, set, or dict.

Here's how to group words by their length into a dictionary:

>>> from itrx import Itr
>>> Itr(("apple", "banana", "carrot")).groupby(len).collect(dict)
{5: ('apple',), 6: ('banana', 'carrot')}

For reference, the equivalent using itertools directly (is fairly readable):

>>> import itertools
>>> {k: tuple(v) for k, v in itertools.groupby(("apple", "banana", "carrot"), key=len)}
{5: ('apple',), 6: ('banana', 'carrot')}

Note:

  1. Using collect(dict) requires an iterable that produces 2-tuples (key-value pairs).
  2. collect(set) is equivalent to a "unique" method.

How Itr Works: Lazy vs. Eager

Most Itr methods are lazy transformations, meaning they return a new Itr instance without immediately processing any data. This allows for arbitrary chaining and efficient memory usage, as items are only processed as they are requested. In most cases, Itr simply acts as a convenient wrapper around itertools, enabling this left-to-right chaining syntax.

  • Combining and splitting: partition, copy, batched, pairwise, rolling, chain, cycle, repeat, product, inspect, intersperse, interleave, chunk_by, zip_longest
  • Transformation and filtering: accumulate, filter, map, starmap, map_while, flatten, flat_map, skip_while, take_while, dedup

However, some methods are eager consumers. These methods iterate over and consume the underlying data, returning concrete values, collections, or aggregates. Examples include:

  • Collection methods: collect, last, next, next_chunk, next_if, nth, position
  • Aggregation methods: count, reduce, max, min, sum, prod, all, any, consume, find, fold
  • Sorting/grouping: sorted_by and groupby sort the entire input up front, and value_counts counts it (most common first, like pandas), so all three consume the whole iterator immediately and must not be used on infinite sources. Use the lazy chunk_by to group consecutive runs without sorting.

Important Considerations

When working with Itr, keep these points in mind:

  • Single-Pass Iterators: Like all Python iterators, Itr instances (and their underlying iterators) can generally only be consumed once. If you need to process the same sequence multiple times, use methods like copy(), cycle(), or repeat() as necessary.
  • No Rewinding: It's not possible to rewind an Itr to an earlier state. You can "preview" the next value using the peek() method, and conditionally consume it with next_if().
  • Infinite Iterators: Be cautious with open-ended iterators (e.g., those from itertools.count() or custom generators). Eager evaluation methods (like collect(), count(), reduce()) will attempt to consume the entire sequence, potentially leading to infinite loops or out-of-memory errors if applied to an infinite source.

Agent skill

itrx ships a SKILL.md for AI coding agents (e.g. Claude Code) covering the Itr API, the lazy/eager split described above, and the common pitfalls (single-pass iterators, infinite sources, groupby vs chunk_by), so an agent doesn't need this whole README in context to write correct Itr chains.

Install it into a project as a symlink to the version installed in the current environment:

uv run itrx-skill --install [PATH]  # default PATH: .agents
uv run itrx-skill --remove [PATH]   # default PATH: .agents

(Or, without uv, activate the virtualenv itrx is installed in and drop the uv run prefix — itrx-skill is a normal console-script entry point, so it's only on PATH while that environment is active.)

This creates (or removes) PATH/skills/itrx, symlinked to the skill bundled inside the installed itrx package, so it always matches the version in use.

API Reference

For a complete list of Itr methods and their detailed descriptions, please refer to the API documentation.

Note: apidoc.md is auto-generated using Itr - see introspect.py.

Examples

Some worked examples can be found in this notebook. Use e.g. pip install itrx[examples] to resolve the extra dependencies.

About

A chainable iterable adaptor

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages