functional-piped
Python has native support for some functional programming functions such as map
and filter
.
This library allows you to use them in a "piped" way,
i.e. s(iterable).map(func)
instead of map(func, iterable)
,
because in any slightly more complex scenarios, the former is much more readable.
For example,
makes much more sense than
Installation
pip install functional-piped
Usage
Then you can use .map
, .filter
, .reduce
, .foreach
, and .zip
to manipulate your iterable in a functional programming way.
If the result is still an iterable, you can use .to()
to collect it into any data type
>>> s([1, 2, 3]).map(lambda x: x + 1).to(list)
[2, 3, 4]
>>> s([1, 2, 3]).map(lambda x: x + 1).filter(lambda x: x % 2).to(list)
[2]
>>> s([1, 2, 3]).map(lambda x: x + 1).to(set)
{2, 3, 4}
>>> (s([1, 2, 3])
... .map(lambda x: x + 1) # [2, 3, 4]
... .filter(lambda x: x % 2 == 0) # [2, 4]
... .reduce(lambda x, y: x + y)) # 2 + 4 = 6
6
>>> s([1, 2, 3]).foreach(print)
1
2
3
Using .zip
and .star
One common use case in Python is
To write equivalent code, you can use s(a_list).zip(b_list)
to zip the two lists together,
and use the .star
attribute to apply .foreach
to the unpacked zipped values
>>> s([1, 2]).zip([3, 4]).to(list)
[(1, 3), (2, 4)]
>>> s([1, 2]).zip([3, 4]).star.foreach(lambda x, y: print(f"{x} + {y}"))
1 + 3
2 + 4
The same thing applies to map and filter:
If you don't use .star
, the callback of each function will receive a tuple:
Naming of .star
comes from the itertools.starmap
, but this concept also
applies to .filter
and .foreach
, so instead of creating a .starmap
method for Stream
, we use the above mentioned syntax there.
Iterable Reusability
s(obj)
behaves exactly the same as obj
in terms of "reusability" when calling iterator/iterable
related methods.
If obj
is an iterable, not iterator:
>>> obj = [1, 2, 3]
>>> stream = s(obj)
>>> stream.map(lambda x: x + 1).to(list)
[2, 3, 4]
>>> stream.map(lambda x: x + 1).to(list)
[2, 3, 4]
If obj
is an iterator: