Использование функции с несколькими параметрами с `map` - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь отобразить функцию, которая принимает 2 аргумента в список:

my_func = lambda index, value: value.upper() if index % 2 else value.lower()

import string
alphabet = string.ascii_lowercase

n = map(my_func, enumerate(alphabet))
for element in n:
    print(element)

Это дает мне TypeError: <lambda>() missing 1 required positional argument: 'value'.

Как правильно отобразить мою лямбду на этот вход?

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

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

Чтобы расширить итеративные аргументы, используйте вместо этого starmap, который "применяет * (звездочку)" при передаче аргументов:

from itertools import starmap

n = starmap(lambda index, value: ..., enumerate(alphabet))
0 голосов
/ 26 апреля 2018

Python не может автоматически распаковать lambda параметры.

Но вы можете обойти это, передав дополнительный range аргумент map:

import string

alphabet = string.ascii_lowercase

n = map(lambda i, v: v.upper() if i % 2 else v.lower(),
        range(len(alphabet)),
        alphabet)

for element in n:
    print(element)

Согласно документам :

карта ( функция , повторяемая , ...)

Возвращает итератор, который применяет функцию каждому элементу повторяемости, дающему результаты. Если дополнительно передаются итерируемые аргументы, функция должна принимать столько аргументов и применяется к элементам из всех итераций параллельно. С несколько итераций, итератор останавливается, когда самая короткая итерация истощены. Для случаев, когда функциональные входы уже расположены в кортежи аргументов см. itertools.starmap ().

0 голосов
/ 26 апреля 2018

Python не может автоматически распаковывать лямбда-параметры. enumerate возвращает tuple, поэтому lambda должен принять этот кортеж в качестве единственного аргумента

Вам нужно:

n = map(lambda t: t[1].upper() if t[0] % 2 else t[1], enumerate(alphabet))

Учитывая теперь уродливость ручной распаковки map + lambda +, я бы порекомендовал альтернативное понимание генератора:

n = (value.upper() if index % 2 else value for index,value in enumerate(alphabet))

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...