What does the star `*` do as an argument to a function and how is it used in Python?

Question:

What does the star * operator do in Python when used as an argument in functions like zip(*x) or fcn(**k) ?

  • How does the interpreter handle it internally?
  • Does it affect performance? Is it fast or slow?
  • When is it useful and where is it not?
  • Should you use it when defining a function or calling it?

Answer:

The star * unpacks a sequence / collection into positional arguments, which can be used when invoking a function:

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

values = (1, 2)

s = sumar(*values)

This unpacks the tuple; what is finally executed is:

s = sumar(1, 2)

The double star ** does the same, but with dictionaries and named arguments:

values = { 'a': 1, 'b': 2 }
s = sumar(**values)

This takes the dictionary and converts it to a string of llave=valor . The result is the execution of:

s = sumar(a=1, b=2)

Star and double star can be combined:

def sumar(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sumar(*values1, **values2)

it will run as:

s = sumar(1, 2, c=10, d=15)

It can also be applied to generators:

s = sumar(*range(4)) -> 6

and inside tuples, lists and dictionaries:

*range(4), 4   -> (0, 1, 2, 3, 4) # Con la coma se considera una tupla.
[*range(4), 4] -> [0, 1, 2, 3, 4]
{*range(4), 4} -> {0, 1, 2, 3, 4}
{'x': 1, **{'y': 2}} -> {'x': 1, 'y': 2}

In defining a function

In addition, functions can be defined with arguments of the type *x and **y . This allows the function to accept any number of positional arguments and / or named arguments, without having to specifically individualize them.

Example:

def sumar(*values):
    s = 0
    for v in values:
        s = s + v
    return s

s = sum(1, 2, 3, 4, 5)

Also using ** :

def get_a(**values):
    return values['a']

s = get_a(a=1, b=2)      # retorna 1

thus you can specify a large number of optional arguments without having to declare them.

They can also be combined:

def sumar(*values, **options):
    s = 0
    for i in values:
        s = s + i
    if "neg" in options:
        if options["neg"]:
            s = -s
    return s

s = sumar(1, 2, 3, 4, 5)            # retorna 15
s = sumar(1, 2, 3, 4, 5, neg=True)  # retorna -15
s = sumar(1, 2, 3, 4, 5, neg=False) # retorna 15

Quick reference

Data

tup = (1, 2, 3, 4)
lis = [5, 6, 7, 8]
dic = {'x': 9, 'y': 10, 'z': 11}
s = {12, 13, 14, 15}

then

print(*tup) -> print(1, 2, 3, 4)
print(*lis) -> print(5, 6, 7, 8)
print(*dic) -> print(x, y, z)
print(*s)   -> print(12, 13, 14, 15)

def simple(x, y, z):
    print(x, y, z)

simple(**dic) -> simple(x=9, y=10, z=11)

References:

4.7.5. Unpacking a list of arguments

PEP 448 – Additional Unpacking Generalizations

Scroll to Top