Using a function with multiple parameters with `map`

前端 未结 3 370
慢半拍i
慢半拍i 2021-01-18 10:57

I\'m trying to map a function that takes 2 arguments to a list:

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

import string
a         


        
相关标签:
3条回答
  • 2021-01-18 11:25

    Python cannot unpack lambda parameters automatically. enumerate returns a tuple, so lambda has to take that tuple as sole argument

    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:

    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)

    0 讨论(0)
  • 2021-01-18 11:38

    Python can't unpack lambda parameters automatically.

    But you can get round this by passing an extra range argument to 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, ...)

    Return an iterator that applies function to every item of iterable, yielding the results. 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. For cases where the function inputs are already arranged into argument tuples, see itertools.starmap().

    0 讨论(0)
  • 2021-01-18 11:45

    map will pass each value from enumerate as a single parameter to the callback, i.e. the lambda will be called with a tuple as argument. 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.

    To expand iterable arguments, use starmap instead, which "applies a * (star)" when passing arguments:

    from itertools import starmap
    
    n = starmap(lambda index, value: ..., enumerate(alphabet))
    
    0 讨论(0)
提交回复
热议问题