Как сделать несколько аргументов для функции map, где один остается в python?

Допустим, что мы добавим функцию следующим образом:

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

мы хотим применить функцию отображения для массива

map(add, [1, 2, 3], 2)

Семантика: я хочу добавить 2 к каждому элементу массива. Но функция map также требует список в третьем аргументе.

Примечание. Я добавляю пример добавления для простоты. Моя оригинальная функция намного сложнее. И, конечно, вариант установки значения по умолчанию y в функции добавления не может быть и речи, поскольку он будет изменен для каждого вызова.

Ответ 1

Один из вариантов - это понимание списка:

[add(x, 2) for x in [1, 2, 3]]

Дополнительные параметры:

a = [1, 2, 3]

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

import itertools
map(add, a, itertools.repeat(2, len(a)))

Ответ 2

Используйте понимание списка.

[x + 2 for x in [1, 2, 3]]

Если вы действительно действительно хотите использовать map, дайте ему анонимную функцию в качестве первого аргумента:

map(lambda x: x + 2, [1,2,3])

Ответ 3

В документах явно указано, что это основное использование для 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]

Фактически, это эквивалентно примеру для repeat в документах:

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

Это обеспечивает хорошее решение lazy-functional-language-y, которое также прекрасно читается в терминах Python-iterator.

Ответ 4

Если у вас есть это, я бы подумал об использовании numpy. Это очень быстро для этих типов операций:

>>> import numpy
>>> numpy.array([1,2,3]) + 2
array([3, 4, 5])

Это предполагает, что ваше реальное приложение выполняет математические операции (которые могут быть векторизованы).

Ответ 5

Карта может содержать несколько аргументов, стандартный способ -

map(add, a, b)

В вашем вопросе это должно быть

map(add, a, [2]*len(a))

Ответ 6

Если вам действительно нужно использовать функцию карты (например, мое назначение класса здесь...), вы можете использовать функцию обертки с 1 аргументом, передавая остальную часть оригинальной в своем теле; то есть:

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


map(myFunc, itterable)

Грязный и уродливый, все еще делает трюк

Ответ 7

Правильный ответ проще, чем вы думаете. Просто выполните:

map(add, [(x, 2) for x in [1,2,3]])

И измените реализацию add, чтобы взять кортеж i.e

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

Это может обрабатывать любой сложный случай использования, когда оба параметра добавления являются динамическими.

Ответ 8

Иногда я разрешал подобные ситуации (например, используя метод pandas.apply) с помощью закрытие

Чтобы использовать их, вы определяете функцию, которая динамически определяет и возвращает оболочку для вашей функции, эффективно делая один из параметров постоянным.

Что-то вроде этого:

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

def add_constant(y):
    def f(x):
        return add(x, y)
    return f

Затем add_constant(y) возвращает функцию, которая может быть использована для добавления y к любому заданному значению:

>>> add_constant(2)(3)
5

Это позволяет использовать его в любой ситуации, когда параметры задаются по одному:

>>> map(add_constant(2), [1,2,3])
[3, 4, 5]

изменить

Если вы не хотите писать функцию закрытия в другом месте, у вас всегда есть возможность построить ее на лету с помощью лямбда-функции:

>>> map(lambda x: add(x, 2), [1, 2, 3])
[3, 4, 5]

Ответ 9

Передача нескольких аргументов функции map.

def q(x,y):
    return x*y

print map (q,range(0,10),range(10,20))

Здесь q - функция с несколькими аргументами, которая вызывает вызовы map(). Убедитесь, что длина обоих диапазонов i.e.

len (range(a,a')) and len (range(b,b')) are equal.

Ответ 10

def func(a, b, c, d): return a + b * c % d

карта (лямбда-x: func (* x), [[1,2,3,4], [5,6,7,8]])

Обернув вызов функции лямбда-выражением и распаковав звездочку, вы можете сделать карту с произвольным числом аргументов.

Ответ 11

Я считаю, что Starmap - это то, что вам нужно:

from itertools import starmap


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

list(startmap(test, [(1, 2, 3), (4, 5, 6)]))

Ответ 12

Другой вариант:

results = []
for x in [1,2,3]:
    z = add(x,2)
    ...
    results += [f(z,x,y)]

Этот формат очень полезен при вызове нескольких функций.

Ответ 13

В: nums = [1, 2, 3]

In: map(add, nums, [2]*len(nums))

Out: [3, 4, 5]