Is there an operator form of map in python?
<p>In Mathematica it is possible to write Map[f,list] as f/@list where /@ is the operator form of Map.  In python there is map(f, list) but is there a similar operator form or a package providing this?</p>

<p>The application is that deeply nested transformations using many maps end up with a lot of brackets whereas operator chaining can be simpler to read (and type).</p>

<p>There is no easy way to do that. Python doesn't provide any way to define custom operators and the set of operators it provides are pretty standard and mostly used for things like numbers and strings. The <code>map</code> object doesn't support anything like that, but nothing prevents you from writing your own class:</p>

<pre><code>class Mapper:
    def __init__(self, f):
        self.f = f
    def __matmul__(self, other):
        return map(self.f, other)
</code></pre>

<p>Used as:</p>

<pre><code>In [3]: list(Mapper(lambda x: x+1) @ [1,2,3,4,5])
Out[3]: [2, 3, 4, 5, 6]
</code></pre>

<p>You can similarly introduce a <code>Filter</code> class:</p>

<pre><code>class Filter:
    def __init__(self, p):
        self.p = p
    def __matmul__(self, other):
        return filter(self.p, other)
</code></pre>

<p>Used as:</p>

<pre><code>In [5]: list(Filter(lambda x: x%2==0) @ range(10))
Out[5]: [0, 2, 4, 6, 8]
</code></pre>

<p>And in fact you can see that this kind of classes are all almost identical, so you could generalize them.</p>

<hr>

<p>Note: <code>@</code> as an operator is new to python3.5.</p>

<hr>

<p>One problem with using this is that <code>@</code> is <em>left</em> associative, which means you aren't able to compose this functions. You can use something like <code>**</code> that is right-associative to compose them easily:</p>

<pre><code>class Filter:
    def __init__(self, p):
        self.p = p
    def __pow__(self, other):
        return filter(self.p, other)

class Mapper:
    def __init__(self, f):
        self.f = f
    def __pow__(self, other):
        return map(self.f, other)
</code></pre>

<p>Which allow:</p>

<pre><code>In [13]: Filter(lambda x: x%2==0) ** Mapper(lambda x: x+1) ** range(10)
Out[13]: &lt;filter at 0x7fe0696bcd68&gt;
</code></pre>

<hr>

<p>For completeness: here's an implementation that generalizes this concept and also works with <code>@</code> by combining the transformations:</p>

<pre><code>class Apply:
    def __init__(self, f):
        self.f = f
    def __matmul__(self, seq_or_apply):
        if isinstance(seq_or_apply, Apply):
            return Apply(lambda seq: self.f(seq_or_apply.f(seq)))
        return self.f(seq_or_apply)

class Mapper(Apply):
    def __init__(self, f):
        super().__init__(lambda x: map(f, x))

class Filter(Apply):
    def __init__(self, p):
        super().__init__(lambda x: filter(p, x))

from functools import reduce

class Reduce(Apply):
    def __init__(self, op, init):
        super().__init__(lambda seq: reduce(op, seq, init))
</code></pre>

<p>Used as:</p>

<pre><code>In [26]: import operator as op
In [27]: Reduce(op.add, -7) @ Filter(lambda x: x%2==0) @ Mapper(lambda x: x+1) @ range(10)
Out[27]: 23
</code></pre>

python functional-programming