简体   繁体   English

使用带有`map`的多个参数的函数

[英]Using a function with multiple parameters with `map`

I'm trying to map a function that takes 2 arguments to a list: 我正在尝试将一个带有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)

This gives me a TypeError: <lambda>() missing 1 required positional argument: 'value' . 这给了我一个TypeError: <lambda>() missing 1 required positional argument: 'value'

What is the correct way to map my lambda onto this input? 将lambda映射到此输入的正确方法是什么?

map will pass each value from enumerate as a single parameter to the callback, ie the lambda will be called with a tuple as argument. map会将enumerate中的每个值作为单个参数传递给回调,即lambda将以元组作为参数调用。 It would be pretty surprising behaviour if map would unpack arguments which look unpackable, since then its behaviour would depend on the values it iterates over. 如果map将解包看起来无法打包的参数,那将是非常令人惊讶的行为,因为它的行为将取决于它迭代的值。

To expand iterable arguments, use starmap instead, which "applies a * (star)" when passing arguments: 要扩展可迭代参数,请改用starmap ,在传递参数时“应用* (星号)”:

from itertools import starmap

n = starmap(lambda index, value: ..., enumerate(alphabet))

Python cannot unpack lambda parameters automatically. Python无法自动解包lambda参数。 enumerate returns a tuple , so lambda has to take that tuple as sole argument enumerate返回一个tuple ,因此lambda必须将该元组作为唯一参数

You need: 你需要:

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

Considering now the ugliness of map + lambda + manual unpacking, I'd advise the alternate generator comprehension instead: 考虑到现在map + lambda +手动拆包的丑陋,我建议替代生成器理解:

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

(I removed the lower() call since your input is already lowercase) (我删除了lower()调用,因为你的输入已经是小写的)

Python can't unpack lambda parameters automatically. Python无法自动解包lambda参数。

But you can get round this by passing an extra range argument to map : 但是你可以通过将一个额外的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)

As per the docs : 根据文档

map ( function , iterable , ...) mapfunctioniterable ,...)

Return an iterator that applies function to every item of iterable, yielding the results. 返回一个迭代器,它将函数应用于每个iterable项,从而产生结果。 If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. 如果传递了其他可迭代参数,则函数必须采用那么多参数,并且并行地应用于所有迭代的项。 With multiple iterables, the iterator stops when the shortest iterable is exhausted. 对于多个迭代,迭代器在最短的iterable耗尽时停止。 For cases where the function inputs are already arranged into argument tuples, see itertools.starmap(). 对于函数输入已经排列成参数元组的情况,请参阅itertools.starmap()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM