Python args kwargs

The *args and **kwargs syntax lets a function accept any number of extra positional or keyword arguments without knowing how many will arrive.

Why variable arguments exist

Sometimes you cannot know in advance how many values a function will receive. A function that adds numbers might get two values one time and ten the next. Python solves this with two special markers in the parameter list: a single asterisk collects extra positional arguments, and a double asterisk collects extra keyword arguments.

Collecting positional arguments with *args

When you prefix a parameter with a single asterisk, Python gathers all remaining positional arguments into a tuple. The name args is only a convention; the asterisk is what does the work. You can then loop over that tuple like any other sequence.

Summing any number of values

def total(*numbers):
    result = 0
    for n in numbers:
        result += n
    return result

print(total(3, 5))          # 8
print(total(1, 2, 3, 4, 5)) # 15
print(total())              # 0

Collecting keyword arguments with **kwargs

A parameter prefixed with two asterisks gathers all extra keyword arguments into a dictionary, where each key is the argument name and each value is what was passed. This is handy for functions that accept flexible options or settings.

Handling named options as a dictionary

def describe(**details):
    for key, value in details.items():
        print(key + ": " + str(value))

describe(name="Leo", age=30, city="Pune")
# name: Leo
# age: 30
# city: Pune

Combining everything and unpacking

You can mix regular parameters, *args, and **kwargs in one definition, but they must appear in that order. The same asterisks also work in reverse: when calling a function, you can use * to spread a list into positional arguments and ** to spread a dictionary into keyword arguments.

Order of parameters and unpacking a call

def report(title, *scores, **info):
    print(title, scores, info)

report("Results", 90, 85, source="exam")
# Results (90, 85) {'source': 'exam'}

values = [90, 85]
extra = {"source": "exam"}
report("Results", *values, **extra)
# Results (90, 85) {'source': 'exam'}
Note: In a definition, args becomes a tuple and kwargs becomes a dictionary. The names are conventional, so *items and **options work exactly the same way.
SyntaxCollectsStored as
*argsExtra positional argumentsTuple
**kwargsExtra keyword argumentsDictionary
*listSpreads a sequence into positional argumentsN/A (used in a call)
**dictSpreads a mapping into keyword argumentsN/A (used in a call)