Expanding tuples into arguments


Suppose I have a function like:

def myfun(a, b, c):
    return (a * 2, b + c, c + b)

Given a tuple some_tuple = (1, "foo", "bar"), how would I use some_tuple to call myfun? This should output the result (2, "foobar", "barfoo").

I know could define myfun so that it accepts the tuple directly, but I want to call the existing myfun.

See also: What do ** (double star/asterisk) and * (star/asterisk) mean in a function call?.

Asked By: AkiRoss



myfun(*some_tuple) does exactly what you request. The * operator simply unpacks the tuple (or any iterable) and passes them as the positional arguments to the function. Read more about unpacking arguments.

Answered By: Alex Martelli

Take a look at the Python tutorial section 4.7.3 and 4.7.4.
It talks about passing tuples as arguments.

I would also consider using named parameters (and passing a dictionary) instead of using a tuple and passing a sequence. I find the use of positional arguments to be a bad practice when the positions are not intuitive or there are multiple parameters.

Answered By: Uri

Note that you can also expand part of argument list:

myfun(1, *("foo", "bar"))
Answered By: Valentas

This is the functional programming method. It lifts the tuple expansion feature out of syntax sugar:

apply_tuple = lambda f, t: f(*t)

Redefine apply_tuple via curry to save a lot of partial calls in the long run:

from toolz import curry
apply_tuple = curry(apply_tuple)

Example usage:

from operator import add, eq
from toolz import thread_last

    [(1,2), (3,4)],
    (map, apply_tuple(add)),
    (eq, [3, 7])
# Prints 'True'

Similar to @Dominykas’s answer, this is a decorator that converts multiargument-accepting functions into tuple-accepting functions:

apply_tuple = lambda f: lambda args: f(*args)

Example 1:

def add(a, b):
    return a + b

three = apply_tuple(add)((1, 2))

Example 2:

def add(a, b):
    return a + b

three = add((1, 2))
Answered By: Mateen Ulhaq
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.