从map()传递几个参数来起作用

时间:2018-03-15 14:18:20

标签: python

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

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)

不起作用。如何从divisor内传递map()参数?

4 个答案:

答案 0 :(得分:9)

您可以使用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)

答案 1 :(得分:7)

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

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

答案 2 :(得分:6)

尝试使用lambda函数

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

而不是pass你的意思是return n

答案 3 :(得分:0)

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

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

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

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)))