Skip to content

transducer library for python, inspired by clojure

License

Notifications You must be signed in to change notification settings

furiel/pyducers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python application

pyducers

Transducer library for python, inspired by clojure

Table of contents

performance

The performance test sums all even numbers below 1000000.

This library is very slow. Using tranducers, calculating that problem takes twice as much time compared to the version that uses a simple for loop, and filters inside the loop. And 50% slower to version that uses the builtin reduce and the filter iterator of the list.

$ python3 perftest.py
time: 0.315	result 249999500000	algorithm: transduce with filter
time: 0.170	result 249999500000	algorithm: with for loop
time: 0.218	result 249999500000	algorithm: builtin reduce with prefiltered list

map

syntax

This behaves the same way as in the standard library.

map(f, coll)

map optionally receives multiple collections. In that case it applies f function for the zip of the collections.

map(f, coll1, coll2, ...)

Supplying only an f function returns a transducer

map(f)

examples

>>> def add(*args):
...     return sum(args)
...
>>> def square(n):
...     return n*n
...
>>> def inc(n):
...     return n+1
...
>>> from pyducers import map, transduce
>>> list(map(inc, [1, 2, 3]))
[2, 3, 4]
>>> list(map(add, [1, 2], [1, 2]))
[2, 4]
>>> transduce(map(square), add, [1, 2, 3])
14
>>> 1*1 + 2*2 + 3*3
14

filter

syntax

This behaves the same way as in the standard library:

filter(f, coll)

Passing only f to filter returns the transducer

filter(f)

examples

>>> def add(*args):
...     return sum(args)
...
>>> def evenp(num):
...     return num % 2 == 0
...
>>> from pyducers import filter, transduce
>>>
>>> list(filter(evenp, [1, 2, 3, 4]))
[2, 4]
>>> transduce(filter(evenp), add, [1, 2, 3, 4], 0)
6

compose

compose function creates a function composition from the provided function. The functions are applied from right to left to the input Note: when using transducer on the composition, the composed transducers are applied in the opposite order: from left to right.

syntax

compose(f, g, ...)

examples

>>> def add(*args):
...     return sum(args)
...
>>> def square(n):
...     return n*n
...
>>> def inc(n):
...     return n+1
...
>>> def two_times(n):
...     return 2*n
...
>>> def evenp(num):
...     return num % 2 == 0
...
>>> from pyducers import compose, transduce, map, filter
>>> compose(square, inc)(1)
4
>>> compose(inc, square)(1)
2
>>> compose(inc, square, two_times)(1)
5
>>> compose(two_times, square, inc)(1)
8
>>> transduce(compose(map(square), filter(evenp)), add, [1, 2, 3, 4], 0)
20

transduce

tranduce reduces over a collection with the tranduced reduce function. Initial value can be optionally supplied.

syntax

If initial_value is not provided, it will be generated by calling reduce_function without arguments: reduce_function()

transduce(transducer, reduce_function, coll, initial_value=None)

examples

>>> def add(*args):
...     return sum(args)
...
>>> def evenp(num):
...     return num % 2 == 0
...
>>> from pyducers import compose, transduce, map, filter
>>> transduce(filter(evenp), add, [1, 2, 3, 4], 0)
6

sequence

sequence collects the result of the transducer into a collection.

syntax

Without transducer, sequence simply transforms collection into a list.

sequence(coll, xf=None)

examples

>>> def evenp(num):
...     return num % 2 == 0
...
>>> from pyducers import filter, sequence
>>> sequence([1, 2])
[1, 2]
>>> sequence([1, 2, 3, 4], filter(evenp))
[2, 4]

About

transducer library for python, inspired by clojure

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages