Skip to content

FluentIterator API

Use the iterator function to create a FluentIterator:

from fluentiter import iterator

my_iter = iterator(["ice", "ice", "baby"])

See below for all the things you can do then.


FluentIterator

Bases: Generic[T], Iterator[T]

Easy to use container for iterables

any(func=bool)

Return True if the given function returns True for any element of this iterator, otherwise return False.

For an empty iterator this is always False.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to evaluate elements, by default bool

bool

Returns:

Type Description
bool

Whether any element of this iterator matches the predicate

Examples:

>>> iterator(["one", "2", "three"]).any(lambda x: x.is_digit())
True
>>> iterator([]).any()
False

chain(other)

Chain another iterable to the end of this iterator. The returned iterator will first yield all items of self and then yield all items of other.

Parameters:

Name Type Description Default
other Iterable[U]

Iterable to chain to this one.

required

Returns:

Type Description
FluentIterator[Union[T, U]]

Chained iterator

Examples:

>>> iterator(["We", "didn't"]).chain(["start", "the", "fire"]).to_list()
    ["We", "didn't", "start", "the", "fire"]

count()

Count the elements in this iterator. This will consume the iterator.

Returns:

Type Description
int

Count of items

Examples:

>>> iterator(range(5)).count()
    5

cycle()

Make an infinite iterator by repeating the values from this one forever. It just goes round and round....

Notes

Do not try to collect an infinite iterator

Returns:

Type Description
CycleIterator[T]

Infite cycling iterator

Examples:

>>> never_ends = iterator("carousel", "wheels on the bus").cycle()
>>> never_ends.next()
    "carousel"
>>> never_ends.next()
    "wheels on the bus"
>>> never_ends.next()
    "carousel"
>>> never_ends.next()
    "wheels on the bus"

enumerate()

Create an iterator which yields tuples of (index, value).

Returns:

Type Description
FluentIterator[Tuple[int, T]]

Iterator of index, value tuples

Examples:

>>> iterator(["zero", "one", "two"]).enumerate().to_list()
    [(0, "zero"), (1, "one"), (2, "two")]

filter(func)

Create a filtered iterator by applying a function to every element to evaluate whether or not it should be yielded.

If the given function returns True the item will be yielded. If the function returns False the iterator will skip the item.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to apply as a filter.

required

Returns:

Type Description
FluentIterator[T]

Filtered iterator

Examples:

>>> iterator([1.0, 1.5, 2.0]).filter(lambda x: x.is_integer()).to_list()
    [1.0, 2.0]

filter_map(func)

A combination of .map and .filter. Apply a given function to every element of the iterator and return the result only if it is not None.

Parameters:

Name Type Description Default
func Callable[[T], Optional[R]]

Function to apply, returns None for elements to be filtered out.

required

Returns:

Type Description
FluentIterator[R]

Iterator of mapped values.

Examples:

>>> (iterator([{"food": "cake"}, {"beverage": "coffee"}])
>>>     .filter_map(lambda x: x.get("food", None))
>>>     .to_list()
>>> )
    ["cake"]

find(func)

Find and return the first element for which the given function returns True.

If no element matches or the iterator is empty, this raises NotFoundError.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to test elements

required

Returns:

Type Description
T

First element which matches the predicate

Raises:

Type Description
NotFoundError

If no element matches

Examples:

>>> iterator(["bert", "waldo", "ernie"]).find(lambda x: x.startswith("w"))
    "waldo"

flat_map(func, exclude=(str, bytes))

Create an iterator which maps a function func across all elements, but also flattens the results if they are iterables.

Notes

By default str and bytes will not be flattened. You can control this via the exclude parameter

Parameters:

Name Type Description Default
func Callable[[T], Union[R, Iterable[R]]]

Function to apply to all elements

required
exclude Tuple[Type, ...]

Types which shall not be flattened, by default (str, bytes)

(str, bytes)

Returns:

Type Description
FluentIterator[R]

Iterator of flattened results

Examples:

>>> dolphins = ["So long", "and thanks", "for all the fish"]
>>> iterator(dolphins).flat_map(lamba x: x.split()).to_list()
    ["So", "long", "and", "thanks", "for", "all", "the", "fish"]

flatten(exclude=(str, bytes))

Make an iterator which which flattens all elements of this iterator.

Notes

By default str and bytes will not be flattened. You can control this via the exclude parameter

Parameters:

Name Type Description Default
exclude Tuple[Type, ...]

Types which shall not be flattened, by default (str, bytes)

(str, bytes)

Returns:

Type Description
FluentIterator[T]

Iterator of flattened elements

Examples:

>>> iterator([("tire", "earth"), ["screen"]]).flatten().to_list()
    ["tire", "earth", "screen"]

fold(initial_value, func)

Fold every element of this iterator into a single value by repeatedly applying func. The given function must takes two parameters, an accumulator A and an element of the iterator T and return the new accumulator A to be used on the next iteration.

For an empty iterator this returns the initial value.

Notes
  • To return the elements instead of the accumulator, use .scan.
  • To use the first element as initial_value, use .reduce.

Parameters:

Name Type Description Default
initial_value A

Initial value of the accumulator

required
func Callable[[S, T], A]

Folding function

required

Returns:

Type Description
A

Folded value

Examples:

>>> iterator(["hot", "dog", "bun"]).fold(1, lambda a, x: a + len(x))
    10

inspect(func)

Return an iterator which applies func to every element, but still yields the original elements. This is useful if the function has some side effect like logging or printing.

Notes

If the elements are mutable, func can still mutate them. Keep this in mind.

Parameters:

Name Type Description Default
func Callable[[T], Any]

Function to apply to every element.

required

Returns:

Type Description
FluentIterator[T]

Iterator of the original elements.

Examples:

>>> lengths = []
>>> iterator(["hot", "dog", "bun"]).inspect(lambda x: lengths.append(len(x))).to_list()
    ["hot", "dog", "bun"]
>>> lengths
    [3, 3, 3]

into(into)

Turn this iterator into something else, by calling a function on it.

This is very useful for collecting the iterator into a different kind of container, e.g. set or tuple

Notes

This method consumes the iterator.

Parameters:

Name Type Description Default
into Callable[[FluentIterator[T]], R]

Function or type to call on this iterator

required

Returns:

Type Description
R

Return value of the given function or instance of the given type

Examples:

>>> iterator([2, 3, 3, 4, 5, 5]).into(set)
    {2, 3, 4, 5}

last()

Return the last element in this iterator. If the iterator does not contain any elements, this returns None.

This consumes the iterator.

Returns:

Type Description
Optional[T]

Last element or None

Raises:

Type Description
EmptyIteratorError

If the iterator has no elements

Examples:

>>> iterator(["foo", "bar", "baz"]).last()
    "baz"
>>> iterator([]).last()
    None

map(func)

Apply a given function func to every element of the iterator, and return an iterator yielding the results of those function calls.

Keep in mind, the function is not applied immediatly but as items are yielded from the iterator.

Parameters:

Name Type Description Default
func Callable[[T], R]

Function to apply to every element.

required

Returns:

Type Description
FluentIterator[R]

Iterator yielding the function call results

Examples:

>>> iterator(["don't", "panic"]).map(lambda x: x.upper()).to_list()
    ["DON'T", "PANIC"]

map_while(func)

A combination of map and take_while. Applies the given function to all elements of the iterator and yields the results. Once the function returns None the iterator will be exhausted and not yield any further items.

Parameters:

Name Type Description Default
func Callable[[T], Union[R, None]]

Function to apply to every element

required

Returns:

Type Description
FluentIterator[R]

Iterator which yields mapped elements until func returns None

Examples:

>>> me = [{"state": "napping"}, {"state": "eating"}, {"state": None}, {"state": "napping"}]
>>> iterator(me).map_while(lambda x: x.get("state", None)).to_list()
    ["napping", "eating"]

max(key=None)

Return the maximum element in this iterator.

If a key is given, the results of key(element) will be compared instead of the elements themselves.

Parameters:

Name Type Description Default
key Optional[Callable[T], Any]

Key to use for comparison, by default None

None

Returns:

Type Description
T

Maximum value

Raises:

Type Description
EmptyIteratorError

If the iterator is empty

Examples:

>>> iterator([42, 1337]).max()
    1337

min(key=None)

Return the minimum element in this iterator.

If a key is given, the results of key(element) will be compared instead of the elements themselves.

Parameters:

Name Type Description Default
key Optional[Callable[T], Any]

Key to use for comparison, by default None

None

Returns:

Type Description
T

Minimum value

Raises:

Type Description
EmptyIteratorError

If the iterator is empty

Examples:

>>> iterator([42, 1337]).min()
    42

next()

Advances the iterator and returns the next value.

Will return None the iterator is exhausted

Returns:

Type Description
Optional[T]

Next element or None if iterator is exhausted

Raises:

Type Description
StopIteration

If there is no next element

nth(index)

Returns the nth element of the iterator. The index starts at 0, i.e. nth(0) returns the first element. If the index is greater than or equal to the length of the iterator, this will return None.

Notes

This method consumes the iterator up to and including index.

Parameters:

Name Type Description Default
index int

The index to return

required

Raises:

Type Description
IndexError

If the iterator has less than index + 1 items

Returns:

Type Description
Optional[T]

Value at the index or None if index is >= iterator length

Examples:

>>> iterator(["n", "t", "h"]).nth(1)
    "t"

partition(func)

Create two iterators from this one, by applying func to every element. All elements for which func(element) == False will become part of the first iterator, all those for which it returns True wil become part of the second iterator

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to apply to sort elements into partitions

required

Returns:

Type Description
Tuple[FluentIterator[T], FluentIterator[T]]

Two iterators, made from elements of this iterator

Examples:

>>> odds, evens = iterator(range(10)).partition(lambda i: bool(i & 1))
>>> odds.to_list()
    [0, 2, 4, 6, 8]
>>> evens.to_list()
    [1, 3, 5, 7, 9]

peek()

Return the next element of the iterator, without advancing it.

Notes

Calling peek multiple times consecutively always returns the same element

Returns:

Type Description
T

The next element in the iterator

Raises:

Type Description
StopIteration

If there is no next element to peek

Examples:

>>> myiter = iterator(["p", "e", "e", "k"])
>>> myiter.peek()
    p
>>> myiter.peek()
    p
    myiter.to_list()
    ["p", "e", "e", "k"]

position(func)

Find the index of the first element for which func(element) == True.

If no item matches or the iterator is empty, returns -1, this behaviour aligns with Pythons str.find.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Predicate to evaluta elements

required

Returns:

Type Description
int

Index of the first element matching the predicate or -1

Examples:

>>> iterator(["bert", "waldo", "ernie"]).position(lambda x: x == "waldo")
    1

product()

Return the product of all elements in this iterator.

Returns:

Type Description
T

The product of all elements

Raises:

Type Description
EmptyIteratorError

If called on an empty iterator

Examples:

>>> iterator([2, 3, 4]).product()
    24

reduce(func)

Reduce all elements into a single element by repeatedly applying func.

The given function must take two parameters, the returned value of the previous iteration and the element of this iteration. For the first iteration this will be the first and second element of this iterator resepctively.

Notes
  • To return the elements instead of the reduction, use .scan.
  • To specify an initial_value, use .fold.

Parameters:

Name Type Description Default
func Callable[[T, R], R]

Reducing function

required

Returns:

Type Description
Union[T, R]

Reduced element or first element of the iterator if it only has one.

Raises:

Type Description
EmptyIteratorError

If called on an empty iterator

Examples:

>>> iterator(["reduce", "reuse", "recycle"]).reduce(lambda x, y: f"{x} {y}")
    "reduce reuse recycle"

rolling_window(size)

Create an iterator of overlapping windows of size size.

The windows will be yielded as tuples containing the original iterators elements

Notes

Requires extra more

Parameters:

Name Type Description Default
size int

Size of the windows

required

Returns:

Type Description
RollingWindowIterator[T]

An iterator of overlapping windows

Raises:

Type Description
ValueError

If size is <= 0

Examples:

>>> iterator([2, 3, 4, 5]).rolling_window(2).to_list()
    [(2, 3), (3, 4), (4, 5)]

scan(initial_state, func)

Create an iterator which holds some internal state and applies some function using that state to every element, returning a tuple of the new state and a mapped element. The new state may then be used by the next iteration.

Notes
  • To end the iteration, the function should raise StopScan.

  • For the curious: The state is returned instead of mutated directly, as many elements in Python (e.g. integers) are immutable and need to be reassigned.

Parameters:

Name Type Description Default
initial_state S

Inital value of the state

required
func Callable[[S, T], Tuple[S, R]]

Function to recieve the state and element as arguments

required

Returns:

Type Description
FluentIterator[R]

Mapped iterator

Examples:

>>> iterator(range(10)).scan(
>>>     initial_state=(0, 0), func=lambda s, x: ((s[1], sum(s) or x), sum(s) or x)
>>> )
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

size_hint()

Get an estimate of the number of elements in this iterator or None if the value can not be estimated.

Returns:

Type Description
Union[int, None]

Length hint

skip(n)

Skip the first n elements of this iterator. After n elements have been skipped, all subsequent elements are yielded.

Parameters:

Name Type Description Default
n int

Number of elements to skip

required

Returns:

Type Description
FluentIterator[T]

Iterator which skips its first n elements

Examples:

>>> iterator(["do", "not", "pet", "the", "dog"]).skip(2).to_list()
    ["pet", "the", "dog"]

skip_while(func)

Skip elements of this iterator by applying the given function to every element while it returns True. After the function has returned False, it will not be applied anymore and all subsequent items are yielded.

The first element where the function returns False is also yielded.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to apply to every element

required

Returns:

Type Description
SkipWhileIterator[T]

Iterator which skips elements while func returns True

Examples:

>>> week = ["Thursday", "Friday", "Saturday", "Sunday"]
>>> iterator(week).skip_while(lambda x: x != "Saturday").to_list()
    ["Saturday", "Sunday"]

step_by(size)

Steps over the iterator with steps of size size. The first element of the iterator is always returned, subsequent items are only returned if there index is a multiple of size.

Parameters:

Name Type Description Default
size int

Size of the step.

required

Returns:

Type Description
FluentIterator[T]

Stepping iterator

Examples:

>>> iterator([1,2,3,4,5]).step_by(2).to_list()
    [1, 3, 5]
>>> iterator([1,2,3,4,5]).step_by(1).to_list()
    [1, 2, 3, 4, 5]

sum()

Sum up all elements in this iterator

Returns:

Type Description
Optional[T]

The sum of all elements or None if iterator is empty

Examples:

>>> iterator([8, 14, 22]).sum()
    42
>>> iterator(["a", "b", "c"]).sum()
    "abc"
>>> iterator([]).sum()
    None

take(n)

Only yield the first n items of the iterator. After n elements have been yielded, the iterator will be exhausted.

Parameters:

Name Type Description Default
n int

Number of items to yield

required

Returns:

Type Description
FluentIterator[T]

Iterator which yields the first n items

Examples:

>>> music = ["on me", "me out", "that"]
>>> iterator(music).take(2).to_list()
    ["on me", "me out"]

take_while(func)

Apply a given function to every element of the iterator and only yield elements while this function returns True. Once the function returns False the iterator will be exhausted and not yield any further items.

Parameters:

Name Type Description Default
func Callable[[T], bool]

Function to apply to every element

required

Returns:

Type Description
TakeWhileIterator[T]

Iterator which yields elements until func returns False

Examples:

>>> week = ["Saturday, "Sunday", "Monday", "Tuesday", "Wednesday"]
>>> iterator(week).take_while(lambda x: x in {"Saturday", "Sunday"}).to_list()
    ["Monday", "Tuesday", "Wednesday"]

to_list()

Collect this iterator into a list, completely consuming it. This is just a convenience method for list().

Returns:

Type Description
List[T]

Collected iterator

Examples:

>>> iterator(["bucket", "to-do", "wish"]).to_list()
    ["bucket", "to-do", "wish"]

tumbling_window(size)

Create an iterator of non-overlapping windows of at most size size.

The windows will be yielded as tuples containing the original iterators elements.

If the count of elements in the iterator is not cleanly divisable by size, the last tuple of elements will be shorter. If this behaviour is undesirable, thos last tuples can be filtered out easily. See the "Examples" section for an example.

Parameters:

Name Type Description Default
size int

Size of the windows

required

Returns:

Type Description
TumblingWindowIterator[T]

An iterator of overlapping windows

Raises:

Type Description
ValueError

If size is <= 0

Examples:

>>> iterator([2, 3, 4, 5]).tumbling_window(2).to_list()
    [(2, 3), (4, 5)]
>>> iterator([2, 3, 4, 5, 6]).tumbling_window(2).to_list()
    [(2, 3), (4, 5), (6)]
>>> # filtering shorter tuples
>>> (iterator([2, 3, 4, 5, 6]).tumbling_window(2).filter(lambda x: len(x) == 2).to_list()
    [(2, 3), (4, 5)]

unzip()

Unzip an iterator of tuples into two iterators, by building the first one from all first elements of each tuple, and the second from all other elements of the tuples.

Returns:

Type Description
Tuple[FluentIterator[T], FluentIterator[U]]

Two new iterators

Examples:

>>> morning, evening = iterator([("coffee", "beer"), ("pancake", "pizza")]).unzip()
>>> morning.to_list()
    ["coffee", "pancake"]
>>> evening.to_list()
    ["beer", "pizza"]

zip(other)

Zip this iterator with another iterable, yielding 2-element tuples where the first element is an element from this iterator and the second element is an element of other.

The iteration stops, as soon as one of the iterators is exhausted.

Parameters:

Name Type Description Default
other Iterable[U]

An Iterable to zip this iterator with

required

Returns:

Type Description
FluentIterator[Tuple[T, U]]

Zipped iterator

Examples:

>>> iterator(["ping", "ping"]).zip(["pong", "pong"]).to_list()
    [("ping", "pong"), ("ping", "pong")]