如何做多个参数来映射函数,其中一个在python中保持不变?

Sha*_*han 125 python

让我们说我们有一个函数添加如下

def add(x, y):
    return x + y
Run Code Online (Sandbox Code Playgroud)

我们想为数组应用map函数

map(add, [1, 2, 3], 2)
Run Code Online (Sandbox Code Playgroud)

语义是我想为数组的每个元素添加2.但是该map函数也需要第三个参数中的列表.

注意:为了简单起见,我将添加示例.我原来的功能要复杂得多.当然,设置y添加功能的默认值的选项是不可能的,因为它将针对每个呼叫进行更改.

Sve*_*ach 157

一个选项是列表理解:

[add(x, 2) for x in [1, 2, 3]]
Run Code Online (Sandbox Code Playgroud)

更多的选择:

a = [1, 2, 3]

import functools
map(functools.partial(add, y=2), a)

import itertools
map(add, a, itertools.repeat(2, len(a)))
Run Code Online (Sandbox Code Playgroud)

  • 是的,但是与地图功能相比它有多快? (3认同)
  • @abarnert:目前还不清楚 OP 使用的是 Python 2 还是 3。为了确保该示例可以在 Python 2 中运行,我包含了该参数。(请注意,`map()` 的行为类似于 Python 2 中的 `zip_longest()`,而它的行为类似于 Python 3 中的 `zip()`。) (3认同)
  • @Shan:在这种情况下看一下 NumPy。如果这对您来说真的是一个问题,那么列表推导式和 `map()` 之间的速度差异无论如何都无济于事。 (2认同)
  • @Shan:正如我之前所说,看看NumPy.它可能有助于加速循环,只要它们可以被矢量化. (2认同)
  • 为什么要将“len(a)”传递给“repeat”?只需使用无限迭代器;它更短,更便宜,并且正是文档建议的“repeat”的主要用途。 (2认同)

aba*_*ert 44

文档明确建议这是主要用途itertools.repeat:

创建一个一遍又一遍地返回对象的迭代器.除非指定了times参数,否则无限期运行.用作map()被调用函数的不变参数的参数.还用于zip()创建元组记录的不变部分.

len([1,2,3])作为times论点,没有理由通过; map第一个可迭代消耗后立即停止,因此无限可迭代完全正常:

>>> from operator import add
>>> from itertools import repeat
>>> list(map(add, [1,2,3], repeat(4)))
[5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

实际上,这相当于repeat文档中的示例:

>>> list(map(pow, range(10), repeat(2)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Run Code Online (Sandbox Code Playgroud)

这使得一个很好的惰性函数语言解决方案在Python-iterator术语中也是完全可读的.

  • 在Python 2中,有必要将长度参数提供给`repeat()`,因为`map()`将一直运行,直到_longest_迭代器在该版本的Python中耗尽,为所有缺失值填充'None`.说"没有理由"传递参数是错误的. (5认同)
  • +1 这应该是公认的答案。它扩展到任意数量的参数,当然,还有一些常量和其他列表或生成器。例如:`def f(x,y,z): \\ return '.'.join([x,y,z])` 然后:`list(map(f, list('abc'), repeat( 'foo'), list('defgh')))` 返回 `['a.foo.d', 'b.foo.e', 'c.foo.f']`。 (3认同)
  • @SvenMarnach 的评论并不小:[Python 3](https://docs.python.org/3/library/functions.html#map) 和 [Python 2](https://docs.python.org/ 2/library/functions.html#map) 的行为差异很大! (2认同)

Fre*_*Foo 31

使用列表理解.

[x + 2 for x in [1, 2, 3]]
Run Code Online (Sandbox Code Playgroud)

如果你真的,真的,真的想要使用map它,给它一个匿名函数作为第一个参数:

map(lambda x: x + 2, [1,2,3])
Run Code Online (Sandbox Code Playgroud)


小智 13

Map可以包含多个参数,标准方式是

map(add, a, b)
Run Code Online (Sandbox Code Playgroud)

在你的问题中,它应该是

map(add, a, [2]*len(a))
Run Code Online (Sandbox Code Playgroud)


jte*_*ace 12

如果你有它,我会考虑使用numpy.这些类型的操作非常快:

>>> import numpy
>>> numpy.array([1,2,3]) + 2
array([3, 4, 5])
Run Code Online (Sandbox Code Playgroud)

这假设您的实际应用程序正在进行数学运算(可以进行矢量化).


Car*_*ala 12

有时我使用闭包解决了类似的情况(例如使用pandas.apply方法)

为了使用它们,您可以定义一个函数,该函数动态定义并返回函数的包装器,从而有效地使其中一个参数成为常量.

像这样的东西:

def add(x, y):
   return x + y

def add_constant(y):
    def f(x):
        return add(x, y)
    return f
Run Code Online (Sandbox Code Playgroud)

然后,add_constant(y)返回一个可用于添加y到任何给定值的函数:

>>> add_constant(2)(3)
5
Run Code Online (Sandbox Code Playgroud)

这允许您在任何一次给出参数的情况下使用它:

>>> map(add_constant(2), [1,2,3])
[3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

编辑

如果你不想在其他地方编写闭包函数,你总是可以使用lambda函数动态构建它:

>>> map(lambda x: add(x, 2), [1, 2, 3])
[3, 4, 5]
Run Code Online (Sandbox Code Playgroud)


Sim*_*nda 10

正确的答案比你想象的要简单.简单地说:

map(add, [(x, 2) for x in [1,2,3]])
Run Code Online (Sandbox Code Playgroud)

并改变add的实现取一个元组即

def add(t):
   x, y = t
   return x+y
Run Code Online (Sandbox Code Playgroud)

这可以处理任何复杂的用例,其中两个添加参数都是动态的.


Tod*_*kov 9

如果你真的真的需要使用map函数(比如我的类赋值......),你可以使用带有1个参数的包装函数,将其余函数传递给它的正文中的原始函数; 即:

extraArguments = value
def myFunc(arg):
    # call the target function
    return Func(arg, extraArguments)


map(myFunc, itterable)
Run Code Online (Sandbox Code Playgroud)

肮脏和丑陋,仍然可以解决问题

  • 一个闭包,我认为这增加了一些东西,再加上一个。类似于部分函数,​​正如接受的答案所具有的那样。 (2认同)

Yuu*_*kio 6

def func(a, b, c, d):
 return a + b * c % d
Run Code Online (Sandbox Code Playgroud)
map(lambda x: func(*x), [[1,2,3,4], [5,6,7,8]])

Run Code Online (Sandbox Code Playgroud)

通过使用 lambda 包装函数调用并使用星号解包,您可以使用任意数量的参数进行映射。


Shq*_*ang 6

我相信星图是你所需要的:

from itertools import starmap


def test(x, y, z):
    return x + y + z

list(starmap(test, [(1, 2, 3), (4, 5, 6)]))
Run Code Online (Sandbox Code Playgroud)