【问题标题】:Using a function with multiple parameters with `map`使用带有多个参数的函数与`map`
【发布时间】:2018-10-07 02:37:22
【问题描述】:

我正在尝试将一个带有 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'

将我的 lambda 映射到此输入的正确方法是什么?

【问题讨论】:

  • 是的,python 3 不能再自动解压lambda 参数了。
  • 我已更正:它不适用于任何 python 版本...
  • 下面的答案有帮助吗?随意接受答案(左侧的绿色勾号),或要求澄清。

标签: python python-3.x lambda typeerror


【解决方案1】:

mapenumerate 中的每个值作为单个参数传递给回调,即 lambda 将使用元组作为参数调用。如果map 会解压缩看起来不可打包的参数,那将是非常令人惊讶的行为,因为它的行为将取决于它迭代的值。

要扩展可迭代参数,请改用starmap,它在传递参数时“应用*(星号)”:

from itertools import starmap

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

【讨论】:

    【解决方案2】:

    Python 无法自动解压 lambda 参数。 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() 调用,因为您的输入已经小写)

    【讨论】:

    • 嗨,很抱歉我的代码格式不好,我只是不知道怎么做。下次我会正确地做。谢谢Jean-François Fabre,我已经理解了这一点,然后我尝试通过 map() 做同样的事情来检查自己。你的解释很好,对我来说是新的。问候
    【解决方案3】:

    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)
    

    根据docs

    映射函数可迭代,...)

    返回一个应用函数的迭代器 到可迭代的每个项目,产生结果。 如果额外 传递了可迭代的参数,函数必须接受那么多参数 并并行应用于所有可迭代的项目。 多个可迭代对象,迭代器在最短的可迭代对象出现时停止 筋疲力尽的。对于功能输入已经安排好的情况 到参数元组中,参见 itertools.starmap()。

    【讨论】:

    • 从来没有想到map 可能需要超过 1 次迭代!
    • @Jean-FrançoisFabre,是的,这只是您曾经看到过的那些技巧之一,并且非常惊讶您不可能忘记。
    • 另外,这就是我喜欢 SO.. 3 个同样可以接受的答案在 10 分钟内!
    • 也完全不同!
    • 请将该n = map(...) 行拆分为多个较短的行。必须滚动查看解决方案对于答案的可读性并不好。我会将 lambda 分配给一个变量。或者您可以将 lambda 称为 my_func,就像问题中的代码一样。
    猜你喜欢
    • 2018-12-06
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多