Вопрос по python – Как сделать несколько аргументов для отображения функции, где один остается неизменным в Python?

100

Допустим, у нас есть функция add следующим образом

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

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

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

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

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

это точно так же, как в Лиспе:map(add,[1,2,3],[2]*3)  в общемmap принимает функцию в качестве первого аргумента, и если эта функция принимаетK аргумент, вы должны следить заK итерация:addTriple(a,b,c) -> map(addTriple,[...],[...],[...]) watashiSHUN

Ваш Ответ

12   ответов
7

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

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


map(myFunc, itterable)

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

Error: User Rate Limit Exceeded
FuncError: User Rate Limit ExceededaddError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
myFuncError: User Rate Limit Exceededreturn Func(arg, extraArguments)
Error: User Rate Limit Exceeded
2

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

from itertools import starmap


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

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

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

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

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

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

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

36

Документы явно предполагают, что это основное использование дляitertools.repeat:

Make an iterator that returns object over and over again. Runs indefinitely unless the times argument is specified. Used as argument to map() for invariant parameters to the called function. Also used with zip() to create an invariant part of a tuple record.

И нет причин для прохода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-functions-language-y, которое также отлично читается в терминах итератора Python.

Error: User Rate Limit ExceededPython 3Error: User Rate Limit ExceededPython 2Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededdef f(x,y,z): \\ return '.'.join([x,y,z])Error: User Rate Limit Exceededlist(map(f, list('abc'), repeat('foo'), list('defgh')))Error: User Rate Limit Exceeded['a.foo.d', 'b.foo.e', 'c.foo.f'].
Error: User Rate Limit Exceededrepeat()Error: User Rate Limit Exceededmap()Error: User Rate Limit ExceededlongestError: User Rate Limit ExceededNoneError: User Rate Limit Exceeded
12

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

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

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

1

Чтобы передать несколько аргументовmap функция.

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

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

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

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

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

results = []
for x in [1,2,3]:
    z = add(x,2)
    ...
    results += [f(z,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]

edit

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

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

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

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

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

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

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

map(lambda x: func(*x), [[1,2,3,4], [5,6,7,8]])

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

139

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

[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)))
Error: User Rate Limit Exceededmap()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededmap()Error: User Rate Limit Exceededzip_longest()Error: User Rate Limit Exceededzip()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Shan
Error: User Rate Limit Exceededadd()Error: User Rate Limit Exceeded
0

В :nums = [1, 2, 3]

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

Из:[3, 4, 5]

Error: User Rate Limit Exceededsearch for similar questionsError: User Rate Limit Exceededask a new questionError: User Rate Limit ExceededAsk questions, get answers, no distractions

Похожие вопросы