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 |
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 |
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 |
Returns:
Type | Description |
---|---|
Optional[T]
|
Value at the index or |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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")]