从 map() 将几个参数传递给函数



例如,如果我想检测数组中的所有奇数并将它们设置为零,我可以使用:

def setToZeroIfOdd(n):
   if n % 2 == 0:
      pass
   else:
      return 0
numbers = range(1,1000)
numbers = map(setToZeroIfOdd, numbers)

这就像一个魅力。

但是当我尝试类似的东西时

def setToZeroIfDivisibleBy(n, divisor):
  if n % divisor == 0:
     return 0
  else:
     pass
numbers = map(setToZeroIfDivisibleBy(divisor=3), numbers)

它期望两个参数。同样

numbers = map(setToZeroIfDivisibleBy, numbers, divisor=3)

不起作用。我怎样才能从map()内部传递divisor论点?

您可以使用functools.partial来制作部分函数

from functools import partial
def setToZeroIfDivisibleBy(n, divisor):
  if n % divisor == 0:
     return 0
  else:
     pass
numbers = range(1,1000)
numbers = map(partial(setToZeroIfDivisibleBy, divisor=3), numbers)

尝试使用 lambda 函数

numbers = map(lambda n: setToZeroIfDivisibleBy(n, divisor=3), numbers)

与其说pass,不如说return n

你创建一个返回函数的函数:

def setToZeroIfDivisibleBy(divisor):
    def callback(n):
        if n % divisor == 0:
            return 0
        else:
            pass
    return callback
numbers = map(setToZeroIfDivisibleBy(3), numbers)

顺便说一句,你可以像else: pass一样完全省略空分支;它什么都不做。由于它会导致None,我认为这也不是您想要的。你可能希望return n那里。

另一种方法,而不是使用partial,是为双参数函数提供无限(或至少足够长(的第二个参数序列:

from itertools import repeat
numbers = map(setToZeroIfDivisibleBy, numbers, repeat(3))

在 Python 2 中,map会根据需要将None附加到两个序列中较短的序列中,以使它们具有相同的长度。假设这会导致问题(要么是因为您的函数无法将None作为输入值处理,要么您最终得到一个无限循环(,您可以使用 itertools.imap ,它在用尽较短的序列后停止:

from itertools import imap, repeat
numbers = list(imap(setToZeroIfDivisibleBy, numbers, repeat(3)))

或者将numbers的长度作为第二个参数传递给repeat,以便两个序列的长度相同。

from itertools import repeat
numbers = map(setToZeroIfDivisibleBy, numbers, repeat(3, len(numbers)))

最新更新