在Python中是否有map的操作形式?

2024-04-27 03:52:15 发布

您现在位置:Python中文网/ 问答频道 /正文

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

应用程序是使用许多映射的深度嵌套转换最终会有许多方括号,而操作符链接可以更易于读取(和键入)。你知道吗


Tags: 功能应用程序map键入链接运算符形式list
1条回答
网友
1楼 · 发布于 2024-04-27 03:52:15

要做到这一点并不容易。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

相关问题 更多 >