Skip to main content
eLearner.app
Module 5 · Lesson 2 of 418/36 in the course~12 min
Module lessons (2/4)

Default and keyword parameters

Function parameters can have default values: if the caller doesn't pass them, the defaults are used. You can also call a function passing parameters by name (keyword arguments).

Default parameters

Python
def saluta(nome, saluto="Ciao"):
    return f"{saluto}, {nome}!"

saluta("Ada")              # 'Ciao, Ada!'
saluta("Ada", "Hello")     # 'Hello, Ada!'

Parameters with defaults must come after those without:

Python
def f(a, b=1):     # OK
def f(a=1, b):     # SyntaxError

Keyword arguments

You can pass arguments by name, in any order, making the call more readable:

Python
def crea_utente(nome, eta, attivo=True):
    return {"nome": nome, "eta": eta, "attivo": attivo}

crea_utente("Ada", 36)
crea_utente(nome="Ada", eta=36, attivo=False)
crea_utente(eta=36, nome="Ada")     # any order when all are keyword

Golden rule: in a call, positional arguments come BEFORE keyword arguments.

Python
crea_utente("Ada", eta=36)            # OK
crea_utente(nome="Ada", 36)           # SyntaxError

⚠️ The mutable default pitfall

NEVER use a mutable object (list, dict, set) as a default value: the default is evaluated ONCE, when the function is defined, and shared across all calls.

Python
def aggiungi(elemento, lista=[]):   # BUG!
    lista.append(elemento)
    return lista

aggiungi(1)    # [1]
aggiungi(2)    # [1, 2]    !!! not [2] as you'd expect
aggiungi(3)    # [1, 2, 3]

The correct pattern: use None as a sentinel and create it inside:

Python
def aggiungi(elemento, lista=None):
    if lista is None:
        lista = []
    lista.append(elemento)
    return lista

The danger of mutable default arguments

Never use mutable objects (like lists or dictionaries) as default values for parameters: for example def add(x, my_list=[]). The default value is evaluated only once when the function is defined, meaning subsequent calls will share the exact same mutable object! The best practice is to use None:

Python
def add(x, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(x)
    return my_list

Try it

Exercise#python.m5.l2.e1
Attempts: 0Loading…

Define `power(base, exponent=2)` that returns base ** exponent. Compute `square = power(5)` and `cube = power(5, exponent=3)`. Evaluate `(square, cube)`.

Loading editor…
Show hint

return base ** exponent

Solution available after 3 attempts

Review exercise

Exercise#python.m5.l2.e2
Attempts: 0Loading…

Define `create_record(name, values=None)` that, when values is None, uses a fresh empty list. Append 1 to values and return the record dict {'name': name, 'values': values}. Call it twice without passing values and assign to `a` and `b`. Evaluate `(a['values'], b['values'])`.

Loading editor…
Show hint

Use None as the default and create the list inside the function.

Solution available after 3 attempts

Additional challenge

Exercise#python.m5.l2.e3
Attempts: 0Loading…

Define a function `greet(name, message="Hello")` that returns the formatted string `"{message}, {name}!"`. Test the function by calling `greet("Bob")` as the last expression.

Loading editor…
Show hint

Use a default parameter message="Hello" and an f-string for the returned greeting.

Solution available after 3 attempts