pytoolz / toolz

A functional standard library for Python.
http://toolz.readthedocs.org/
Other
4.7k stars 264 forks source link

Pipe over a sequence #233

Open ajfriend opened 9 years ago

ajfriend commented 9 years ago

I find that I often want to map a sequence of functions over a list of items.

I realize I could do

map(compose(func3, func2, func1), seq)

but it feels more natural to do use something closer to the pipe syntax, like

pipseq(seq, func1, func2, func3)

which could be implemented with either one of the following

def pipeseq(seq, *funcs):
    for func in funcs:
        seq = map(func, seq)
    return seq

def pipeseq2(seq, *funcs):
    for item in seq:
        yield pipe(item, *funcs)

I realize that it doesn't make sense to pollute the toolz namespace with too many functions. Consider this a vote for this one tho. I'd certainly use it.

eriknw commented 9 years ago

Thanks for the feedback! I bet you're not the only one who would use such a function. The preferred way to do this right now is either with compose (as you showed) or with pipe and curried map:

In[10]: list(map(compose(inc, double), range(3)))
Out[10]: [1, 3, 5]

In[11]: from toolz.curried import map

In [12]: list(pipe(range(3), map(double), map(inc)))
Out[12]: [1, 3, 5]

In [13]: list(pipeseq(range(3), double, inc))
Out[13]: [1, 3, 5]
ajfriend commented 9 years ago

Yeah, I was using the curried map version a lot, and repeating map so often that, for long lists of functions, I began writing pipe(seq, *map(map,(func1, func2, func3))). But that's kind of gross, so I started using something like pipeseq.

mrocklin commented 9 years ago

I suggest that we put things like this in the sandbox, watch how they're used, and then either promote or retire them as appropriate in six months.

ajfriend commented 9 years ago

Cool. I'll make a pull request.

Digenis commented 9 years ago

I think this may raise the question whether all functoolz should get an equivalent.

ajfriend commented 9 years ago

True, but I think pipe is pretty natural, and (for me, at least) would be the most useful. Also, what functoolz would need to be extended, other than thread_first and thread_last?