在Mathematica中,可以将Map [f,list]写为f / @ list,其中/ @是Map的运算符形式。在python中有map(f,list)但有类似的运算符表单或提供此的包吗?
应用程序是使用许多映射的深层嵌套转换最终会有很多括号,而操作符链可以更容易阅读(和键入)。
答案 0 :(得分:2)
没有简单的方法可以做到这一点。 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]
您可以类似地介绍Filter
类:
class Filter:
def __init__(self, p):
self.p = p
def __matmul__(self, other):
return filter(self.p, other)
用作:
In [5]: list(Filter(lambda x: x%2==0) @ range(10))
Out[5]: [0, 2, 4, 6, 8]
事实上你可以看到这种类几乎都是相同的,所以你可以概括它们。
注意:@
作为运算符是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>
为了完整性:这是一个实现,它概括了这个概念,并且通过组合转换也可以与@
一起使用:
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))
用作:
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