Learn

Short lessons with real code you can edit and run on the page.

Function Arguments in Python

Lesson 23 Python 3.14 Runs in your browser Updated
In short

Arguments are the values you pass to a function when you call it. Python matches them to parameters by position or by name, and defaults fill in missing ones. *args collects extra positional arguments, and **kwargs collects extra keyword arguments.

Key facts

  • Positional arguments fill parameters in order. Keyword arguments, such as age=36, fill them by name.
  • def power(base, exponent=2): gives exponent a default, used when the call leaves it out.
  • A default is evaluated once, when def runs, so a list default is shared by every call that uses it. Use None and create the list inside.
  • *args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary.
  • f(*items) passes a list as separate arguments, and f(**options) passes a dictionary as keyword arguments.

What are function arguments in Python?

Arguments are the values you pass to a function when you call it. Before the body runs, Python assigns each argument to a parameter, matching them by position or by name.

Python
def describe(name, age):
    print(f"{name} is {age} years old.")

describe("Ada", 36)
describe(age=36, name="Ada")
Output
Ada is 36 years old.
Ada is 36 years old.

The first call passes positional arguments, so the first value goes to the first parameter. The second call passes keyword arguments such as age=36, which name the parameter they fill, so their order doesn't matter. Both calls give the function the same two values.

What is the difference between positional and keyword arguments?

A positional argument is matched by its place in the call, and a keyword argument by its name. One call can use both, as long as every positional argument comes first.

Python
def describe(name, age):
    print(f"{name} is {age} years old.")

describe(36, "Ada")
describe("Grace", age=85)
Output
36 is Ada years old.
Grace is 85 years old.

Swapping the positional arguments raises no error here. Python fills the parameters in order, so the function prints nonsense. Keyword arguments prevent this when a call passes several values that could be mixed up. The second call mixes both kinds correctly, with the positional argument first.

You have used keyword arguments before. The sep and end arguments of print(), from the input and output lesson, are keyword arguments, and so is key in sort().

How do I give a parameter a default value?

Write the default after the parameter's name with an equals sign, as in exponent=2. A call can then leave that argument out, and the parameter takes the default.

Python
def power(base, exponent=2):
    return base ** exponent

print(power(5))
print(power(2, 10))
print(power(3, exponent=3))
Output
25
1024
27

Parameters with a default are optional, and parameters without one are required. A required parameter can't follow one with a default, so def power(exponent=2, base): is a SyntaxError. The one exception is a keyword-only parameter, which the *args section explains and the parameter order example shows.

PEP 8 recommends no spaces around the = in a default like this one and in a keyword argument.

Why does a default list keep its items between calls?

Python evaluates a default value once, when the def statement runs, not each time the function is called. Every call that uses the default gets that same object, so a default list collects the items from every earlier call that used it.

Python
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))
Output
['a']
['a', 'b']

You might expect the second call to return ['b'], but the list created when def ran still holds 'a'. The fix is a default of None and a new list created inside the function, where the code runs on every call.

Python
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("a"))
print(add_item("b"))
Output
['a']
['b']

The same trap applies to a dictionary or a set used as a default. Numbers, strings, None and tuples of them are safe defaults, because they can't be changed in place.

What does *args do in Python?

*args collects any number of extra positional arguments into a tuple. The star does the work, and args is only the usual name, so *numbers behaves the same way.

Python
def total(*numbers):
    print(numbers)
    return sum(numbers)

print(total(1, 2, 3))
print(total())
Output
(1, 2, 3)
6
()
0

The three arguments arrive as the tuple (1, 2, 3), and a call with no arguments gets an empty tuple. print() is built the same way, so it accepts any number of values.

Any parameter after *args can only be passed by name, because the star collects every remaining positional argument. Such parameters are called keyword-only. The sep parameter of print() is one, so it must always be written as sep=.

Python
def join_words(*words, sep=" "):
    return sep.join(words)

print(join_words("red", "green", "blue"))
print(join_words("red", "green", "blue", sep=", "))
Output
red green blue
red, green, blue

What does **kwargs do in Python?

**kwargs collects any extra keyword arguments into a dictionary. Each argument's name becomes a key, and its value becomes that key's value. The name kwargs, short for keyword arguments, is only a convention.

Python
def show(title, **details):
    print(title)
    print(details)

show("Ada Lovelace", born=1815, field="mathematics")
Output
Ada Lovelace
{'born': 1815, 'field': 'mathematics'}

The first argument fills title. The two keyword arguments match no parameter, so they end up in details. It's an ordinary dictionary, so you can loop over it with items() or read a value with get().

How do I pass a list or a dictionary as separate arguments?

Put * before a list or tuple in the call, or ** before a dictionary. Python unpacks the list's items into positional arguments and the dictionary's pairs into keyword arguments.

Python
def describe(name, age):
    print(f"{name} is {age} years old.")

person = ["Ada", 36]
describe(*person)
info = {"name": "Grace", "age": 85}
describe(**info)
Output
Ada is 36 years old.
Grace is 85 years old.

describe(*person) makes the same call as describe("Ada", 36), and print(*range(1, 11)) uses the same star to print 1 to 10 on one line.

With describe(**info), a key that matches no parameter raises a TypeError about an unexpected keyword argument, and a missing key raises one about a missing argument.

What is the difference between *args and **kwargs?

*args collects extra positional arguments into a tuple, and **kwargs collects extra keyword arguments into a dictionary. A function can take both, with *args first.

Python
def report(*args, **kwargs):
    print(args)
    print(kwargs)

report(1, 2, unit="cm")
Output
(1, 2)
{'unit': 'cm'}
Python *args compared with **kwargs
Question*args**kwargs
What does it collect?Extra positional argumentsExtra keyword arguments
What type is it?A tuple, such as (1, 2)A dictionary, such as {'unit': 'cm'}
Example callreport(1, 2)report(unit="cm")
The star in a call*items unpacks a list or tuple**options unpacks a dictionary

In what order do parameters go in a Python function?

Parameters without defaults come first, then ones with defaults, then *args, then keyword-only parameters, then **kwargs. Python checks the order when it reads the def line and reports a wrong order as a SyntaxError before anything runs.

Python
def order(a, b=2, *args, c, d=4, **kwargs):
    print(a, b, args, c, d, kwargs)

order(1, 3, 5, 6, c=7, e=8)
Output
1 3 (5, 6) 7 4 {'e': 8}

The 1 and 3 fill a and b, and the 5 and 6 go to args. c is keyword-only, so it must be passed by name, and it's allowed to have no default even though b has one. d keeps its default of 4, and e matches no parameter, so it lands in kwargs. Few real functions use every kind at once.

Common mistakes with function arguments in Python

Besides the missing-argument TypeError from the functions lesson, these four messages come up often, shown here for greet(name, greeting="Hello"). The SyntaxError appears before any line of the program runs.

  • TypeError: greet() takes from 1 to 2 positional arguments but 3 were given. The call passed more positional values than the function has parameters for. Remove the extra value, or add a parameter or *args to collect it.
  • TypeError: greet() got an unexpected keyword argument 'greting'. A keyword argument's name matches no parameter, here because of a typo. When a parameter's name is close, Python adds a suggestion such as Did you mean 'greeting'?
  • TypeError: greet() got multiple values for argument 'name'. The same parameter was filled twice, once by position and once by name, as in greet("Ada", name="Ada").
  • SyntaxError: positional argument follows keyword argument. A positional argument came after a keyword argument in the call. Put every positional argument first.

Run the two broken programs to see the messages, then fix them in the editor.

Python
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Ada", greting="Hi")
Output
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    greet("Ada", greting="Hi")
    ~~~~~^^^^^^^^^^^^^^^^^^^^^
TypeError: greet() got an unexpected keyword argument 'greting'. Did you mean 'greeting'?
Python
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet(greeting="Hi", "Ada")
Output
  File "main.py", line 4
    greet(greeting="Hi", "Ada")
                              ^
SyntaxError: positional argument follows keyword argument

Exercise

Give greeting a default value of "Hello" without changing the calls, so the program prints Hello, Ada! and then Hi, Grace! on two lines. The starter stops with a TypeError, because the first call leaves out a required argument.

Python
def greet(name, greeting):
    print(f"{greeting}, {name}!")

greet("Ada")
greet("Grace", "Hi")
Output
Show the solution
def greet(name, greeting="Hello"):
    print(f"{greeting}, {name}!")

greet("Ada")
greet("Grace", "Hi")

Quiz

This quiz has 5 questions. Pick an answer to see why it is right or wrong.

  1. 1What does this program print?

    def f(a, b=2):
        return a + b
    
    print(f(1))
  2. 2What does this program print?

    def count(*args):
        return len(args)
    
    print(count("a", "b", "c"))
  3. 3What does this program print?

    def f(**kwargs):
        print(type(kwargs))
    
    f(x=1)
  4. 4What does this program print?

    def add(x, items=[]):
        items.append(x)
        return items
    
    add(1)
    print(add(2))
  5. 5A function is defined as def f(a, b). Which of these calls is a syntax error?

Frequently asked questions

What are *args and **kwargs in Python?
*args collects any extra positional arguments into a tuple, and **kwargs collects any extra keyword arguments into a dictionary. They let a function accept any number of arguments, the way print() accepts any number of values.
How do I pass a list as separate arguments in Python?
Put * before the list in the call, as in print(*items), and Python passes its items as separate positional arguments. Two stars before a dictionary pass its pairs as keyword arguments, and each key must match a parameter name unless the function takes **kwargs.
What is a keyword argument in Python?
A keyword argument is passed by name instead of by position, as in describe(age=36). Keyword arguments can come in any order, but every one of them must follow the positional arguments in the call.
How do I give a function parameter a default value?
Write the default after the name with an equals sign, as in def greet(name, greeting="Hello"). A call can then leave that argument out. A parameter without a default can't come after one that has a default, unless it is keyword-only, such as a parameter placed after *args.
Why is a mutable default argument a problem in Python?
A default is evaluated once, when the def statement runs, so a list or dictionary default is shared by every call that uses it. Items added in one call are still there in the next. Use None as the default and create the list inside the function.
Do the names args and kwargs matter in Python?
No. The single and double stars do the work, so *numbers and **options behave the same way. args and kwargs are a convention that most Python code follows.
What do / and * mean in a Python function's parameter list?
Parameters before a / can only be passed by position, and parameters after a lone * can only be passed by name. help(sorted) shows sorted(iterable, /, *, key=None, reverse=False), so the list is passed by position and key must always be named.