Skip to content

lukapeschke/chainit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

chainit

Documentation available here: https://lukapeschke.github.io/chainit/

This library provides the ChainIt class, a wrapper around stdlib's itertools module, allowing to chain operations on iterables, resulting in easier-to-read code.

import typing as t

def fib() -> t.Iterable[int]:
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# Allows to write things like this...
(
    ChainIt(fib())
    .filter(lambda x: x % 2 == 0)
    .map(lambda x: x // 2)
    .flat_map(range)
    .take_while(lambda x: x < 6)
    .collect_list()
)

# ...rather than like this
from itertools import chain as ichain, islice, takewhile

list(
    takewhile(
        lambda x: x < 6,
        ichain.from_iterable(
            map(lambda x: range(x // 2), filter(lambda x: x % 2 == 0, fib()))
        ),
    )
)

Installation

pip install chainit

Examples

Decorator

In addition to ChainIt, the library provides a chainit decorator. It makes a function returning an iterable return a ChainIt instead:

@chainit
def fac():
    n = 0
    fac = 1
    while True:
        yield fac
        n += 1
        fac *= n

assert fac().enumerate().take(5).collect() == ((0, 1), (1, 1), (2, 2), (3, 6), (4, 24))

Using a ChainIt instance as an iterable

assert list(fac().take(3)) == [1, 1, 2]

for idx, x in fac().enumerate():
    if idx > 3:
        break
    print(x)