python中是否有map的操作符形式?

python中是否有map的操作符形式?,python,functional-programming,Python,Functional Programming,在Mathematica中,可以将Map[f,list]写成f/@list,其中/@是Map的运算符形式。python中有map(f,list),但是否有类似的操作符形式或提供此功能的包 应用是,使用许多映射的深度嵌套转换最终会有很多括号,而运算符链接则更易于读取(和键入)。没有简单的方法可以做到这一点。Python不提供任何定义自定义运算符的方法,它提供的一组运算符非常标准,主要用于数字和字符串等。map对象不支持类似的内容,但没有任何东西阻止您编写自己的类: class Mapper:

在Mathematica中,可以将Map[f,list]写成f/@list,其中/@是Map的运算符形式。python中有map(f,list),但是否有类似的操作符形式或提供此功能的包


应用是,使用许多映射的深度嵌套转换最终会有很多括号,而运算符链接则更易于读取(和键入)。

没有简单的方法可以做到这一点。Python不提供任何定义自定义运算符的方法,它提供的一组运算符非常标准,主要用于数字和字符串等。
map
对象不支持类似的内容,但没有任何东西阻止您编写自己的类:

class Mapper:
    def __init__(self, f):
        self.f = f
    def __matmul__(self, other):
        return map(self.f, other)
用作:

In [3]: list(Mapper(lambda x: x+1) @ [1,2,3,4,5])
Out[3]: [2, 3, 4, 5, 6]
In [5]: list(Filter(lambda x: x%2==0) @ range(10))
Out[5]: [0, 2, 4, 6, 8]
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
您可以类似地引入
过滤器
类:

class Filter:
    def __init__(self, p):
        self.p = p
    def __matmul__(self, other):
        return filter(self.p, other)
用作:

In [3]: list(Mapper(lambda x: x+1) @ [1,2,3,4,5])
Out[3]: [2, 3, 4, 5, 6]
In [5]: list(Filter(lambda x: x%2==0) @ range(10))
Out[5]: [0, 2, 4, 6, 8]
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
事实上,你们可以看到这类类几乎都是相同的,所以你们可以对它们进行推广


注意:
@
作为操作符是python3.5的新成员


使用此函数的一个问题是,
@
是左关联的,这意味着您无法编写此函数。您可以使用类似于
**
的方法轻松组合它们:

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)
允许:

In [13]: Filter(lambda x: x%2==0) ** Mapper(lambda x: x+1) ** range(10)
Out[13]: <filter at 0x7fe0696bcd68>
用作:

In [3]: list(Mapper(lambda x: x+1) @ [1,2,3,4,5])
Out[3]: [2, 3, 4, 5, 6]
In [5]: list(Filter(lambda x: x%2==0) @ range(10))
Out[5]: [0, 2, 4, 6, 8]
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

不,只有函数。考虑使用列表理解来编写更多的可读代码,和/或提取命名良好的函数。我认为这不是它的正常使用作为关键字参数解包?@Ymareth
**
这里是求幂运算符,例如:
2**3==8
。如您所见,最后一个类定义了特殊方法
\uuuu pow\uuuu
,当
**
操作符应用于某个对象时调用该方法。在这种情况下,它所做的是将
映射
过滤器
应用于右侧操作数。@Ymareth我不得不使用它,因为AFAIK是唯一正确的关联运算符,即
2**2**3==2**(2**3)
而不是
(2**2)**3
。这对于上面的代码很重要,因为我们需要分组
过滤器(…)**(映射器(…)**输入)
,而不是分组
(过滤器(…))**Mapper(…)**输入)
,这将触发错误(这是
@
发生的情况)。@Ymareth我已经开始并添加了一个泛化,这也可以通过组合函数来使用
@
(虽然测试不多,可能有缺点…)