Reputation: 12283
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? - the corresponding question for people who encounter the syntax and are confused by it.
Upvotes: 574
Views: 372380
Reputation: 8135
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
thread_last(
[(1,2), (3,4)],
(map, apply_tuple(add)),
list,
(eq, [3, 7])
)
# Prints 'True'
Upvotes: 9
Reputation: 27271
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:
@apply_tuple
def add(a, b):
return a + b
three = add((1, 2))
Upvotes: 7
Reputation: 882691
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.
Upvotes: 1002
Reputation: 89839
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.
Upvotes: 16
Reputation: 2245
Note that you can also expand part of argument list:
myfun(1, *("foo", "bar"))
Upvotes: 83