Search code examples
pythonpython-3.xfunctional-programmingvariable-assignmentiterable-unpacking

map with function for each element?


Very often I process single elements of tuples like this:

size, duration, name = some_external_function()
size = int(size)
duration = float(duration)
name = name.strip().lower()

If some_external_function would return some equally typed tuple I could use map in order to have a (more functional) closed expression:

size, duration, name = map(magic, some_external_function())

Is there something like an element wise map? Something I could run like this:

size, duration, name = map2((int, float, strip), some_external_function())

Update: I know I can use comprehension together with zip, e.g.

size, duration, name = [f(v) for f, v in zip(
   (int, float, str.strip), some_external_function())]

-- I'm looking for a 'pythonic' (best: built-in) solution!

To the Python developers:

What about

(size)int, (duration)float, (name)str.strip = some_external_function()

? If I see this in any upcoming Python version, I'll send you a beer :)


Solution

  • Map does not really apply here. It comes in handy when you want to apply a simple function over all elements of a list, such as map(float, list_ints).

    There isn't one explicit built-in function to do this. However, a way to simplify your approach and avoid n separate calls to the functions to be applied, could be to define an iterable containing the functions, and apply them to the returned non-unpacked tuple from the function on a generator comprehension and then unpack them:

    funcs = int, float, lambda x: x.strip().lower()
    t = 1., 2, 'Some String  ' # example returned tuple
    
    size, duration, name = (f(i) for f,i in zip(funcs, t))
    

    Or perhaps a little cleaner:

    def transform(t, funcs):
        return (f(i) for f,i in zip(funcs, t))
    
    size, duration, name = transform(t, funcs)
    

    size
    # 1
    duration
    # 2.0
    name
    # 'some string'