Skip to main content

Implementation of some rich-iterator concept

Project description

iter2

This library provides implementation of rich-iterator concept, inspired by Rust's std::iter::Iterator, Java's Stream and more-itertools library.

Usage

The main object of library is iter2. It behaves like built-in iter except that it creates an instance of rich-iterator.

iter2(['dzen', 'of', 'python']).map(str.capitalize).join(' ')  # 'Dzen Of Python'

Every method of rich-iterator that returns new iterator makes original rich-iterator invalid, so it cannot be used in any iteration process. This behaviour can be bypassed with ref method.

Original iterator can be retrieved with raw method:

orig = iter2.range(5).raw()
tuple(orig)  # (0, 1, 2, 3, 4)

iter2 has some methods to build sequences of values:

iter2.of('a', 'b', 'cde').join()  # 'abcde'
iter2.range(5).map(str).join()  # '01234'
iter2.count_from(100).take(5).map(str).join('->')  # '100->101->102->103->104'
iter2.numeric_range(1.0, 3.5, 0.3).to_tuple()  # (1.0, 1.3, 1.6, 1.9, 2.2, 2.5, 2.8, 3.1, 3.4)
# and some other ...

and some algorithm-methods on multiple iterables:

iter2.cartesian_product(range(2), repeat=2).to_tuple()  # ((0, 0), (0, 1), (1, 0), (1, 1))
iter2.zip_longest(range(3), range(1, 5), fillvalue=-1).to_tuple()  # ((0, 1), (1, 2), (2, 3), (-1, 4))
iter2.chain(['Somewhere', 'over'], ['the', 'Rainbow']).join(' ')  # 'Somewhere over the Rainbow
# and some other ...

Comparison

Here are some examples of usage compared with builtins-and-itertools-based implementations:

from itertools import islice
from functools import reduce
import operator

from iter2 import iter2

square = lambda x: x ** 2
odd = lambda x: x % 2 == 1

def fibonacci():
    a = b = 1
    while True:
        yield a
        a, b = b, a + b


# Example 1:
cool_song = 'Somewhere over the Rainbow'
# "from `cool_song` take capital characters and join them with '+'"
iter2(cool_song).filter(str.isupper).join('+')
# vs
# "with '+' join capital characters from `cool_song`"
'+'.join(filter(str.isupper, cool_song)) 


# Example 2:
# "for values in 0..99 take squares of them that are odd and sum them" (sounds like algo)
iter2.range(100).map(square).filter(odd).sum()
# vs
# "sum values that are odd that are squares of values in 0..99" (sounds like shit)
sum(filter(odd, map(square, range(100))))
# "sum squares of values in 0..99 that are odd"
sum(x ** 2 for x in range(100) if x % 2 == 1) # luckily, oddity doesn't change on squaring


# Example 3: "Playing with infinite sequences"
(iter2(fibonacci())
    .drop(10)
    .filter(odd)
    .map(square)
    .take(5)
    .product())  # shortcut for `.fold(operator.mul)`
# vs
reduce(operator.mul,islice(map(square, filter(odd, islice(fibonacci(), 10, None))), 5))  # (counting braces balance and commas positions)
# (to make clearer):
reduce(
    operator.mul,
    islice(
        map(
            square, 
            filter(
                odd, 
                islice(fibonacci(), 10, None)
            )
        ), 
        5
    )
) # or not?

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iter2-1.0rc0.tar.gz (27.5 kB view hashes)

Uploaded Source

Built Distribution

iter2-1.0rc0-py3-none-any.whl (36.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page