Iterating Over Tuples and Dictionaries
Use *args for extra positional arguments and **kwargs for keyword arguments. Inside the function, the collected values behave like a tuple and a dictionary, so they can be iterated over.
Try it: Binding Arguments to Parameters
How Python matches a call's arguments to a function's parameters — positionals left to right, extras into *args, keywords by name, defaults for the rest, unknown names into **kwargs — and the exact SyntaxError or TypeError when a call doesn't fit, including the shared mutable default.
How it works
- The parser checks the call first: a positional after a keyword, or a repeated keyword, is a SyntaxError before anything runs.
- At the call site, *list spreads into separate positional arguments and **dict into keyword arguments.
- Positional arguments fill the parameters left to right; leftovers go into the *args tuple.
- Each keyword matches a parameter by exact name (a second value is 'got multiple values'); unknown names go into **kwargs or raise 'unexpected keyword argument'.
- Then: too many positionals, or a required parameter still empty, is a TypeError; otherwise defaults fill the rest.
- Defaults are evaluated once, at def time: a list default is the same object in every call.
Default run (13 steps): def greet(…) runs once: it creates the function and evaluates its default values right now. Then the call greet('Ann', 'Hi', *[7, 8], sep='-', mood='happy') starts. … Done. Printed: {'name': 'Ann', 'greeting': 'Hi', 'sep': '-', 'args': (7, 8), 'kwargs': {'mood': 'happy'}}.
Simplified: Five hand-written signatures with no positional-only (/) parameters; argument values are small literals (ints, short strs, True/False/None, flat lists). Error messages are CPython 3.12's (3.13+ may add a 'Did you mean' hint).
Loading the simulation…
Why Variable Inputs Matter
Suppose a function must add numbers, but one user supplies three numbers while another supplies five or ten. Defining a separate function for every possible number of inputs would be impractical. Python provides variable argument lists so one function can accept an unknown number of arguments. The asterisk syntax collects extra positional arguments, and the double-asterisk syntax collects keyword arguments.
Use *args for extra positional arguments and **kwargs for keyword arguments. Inside the function, the collected values behave like a tuple and a dictionary, so they can be iterated over.
Packing Positional Arguments
When a function defines a parameter such as *numbers, Python collects the extra positional arguments supplied at the call site into one tuple named numbers inside the function. The tuple preserves the order in which the positional arguments were supplied. Because numbers is a tuple, the function can process it with a loop just as it would process any other tuple.
def total(initial, *numbers):
result = initial
for number in numbers:
result = result + number
return result
answer = total(10, 1, 2, 3)
print(answer)- 1The call supplies four positional values.
- 2The fixed parameter initial receives 10.
- 3The *numbers parameter collects 1, 2, and 3 into a tuple.
- 4The loop adds each tuple value to result.
- 5The function returns 16.
- initial receives the first positional argument, 10.
- numbers receives the remaining positional arguments as the tuple (1, 2, 3).
- The loop visits 1, then 2, then 3.
- The accumulated result becomes 11, then 13, then 16.
16Packing Keyword Arguments
A parameter written as **keywords collects keyword arguments into a dictionary. Each keyword supplies a name and a value, so the function can process the collected key-value pairs. Since keywords behaves like a dictionary inside the function, it can be iterated over like any other dictionary.
def total(initial, *numbers, **keywords):
result = initial
for number in numbers:
result = result + number
for value in keywords.values():
result = result + value
return result
answer = total(10, 1, 2, 3, vegetables=50, fruits=100)
print(answer)- 1Start result at 10.
- 2Iterate through numbers and add 1, 2, and 3, producing 16.
- 3Iterate through the values in keywords and add 50 and 100.
- 4Return 166.
- initial receives 10.
- numbers receives (1, 2, 3).
- keywords receives the keyword arguments vegetables=50 and fruits=100.
- The positional values and keyword values are all added to the initial value.
166Tracing a Flexible Calculation
What do you think happens?
What will total(10, 1, 2, 3, vegetables=50, fruits=100) return if the function adds the initial value, every value in *numbers, and every value in **keywords?
Reveal answer
166
The initial value is 10. The extra positional values contribute 1 + 2 + 3, giving 16. The keyword values contribute 50 + 100, giving a final result of 166.
Following Every Argument
Trace total(10, 1, 2, 3, vegetables=50, fruits=100) when the function adds all collected values.
- 1Fixed parameter
The first positional argument, 10, is assigned to initial.
- 2Positional tuple
The remaining positional arguments are packed into numbers as (1, 2, 3).
- 3Keyword dictionary
The named arguments are packed into keywords with entries for vegetables equal to 50 and fruits equal to 100.
- 4Tuple iteration
The function processes 1, 2, and 3, changing the running total from 10 to 16.
- 5Dictionary iteration
The function processes the keyword values 50 and 100, changing the running total from 16 to 166.
166
12
30
27The same function handles all three calls even though each call supplies a different number of values after multiplier. In the first call, the tuple is (1, 2, 3), so the calculation is 2 times 1 plus 2 times 2 plus 2 times 3, which equals 12. In the second call, the tuple is (5, 10, 15), producing 30. In the third call, the tuple is (4, 5), producing 27.
Choosing a Clear Function Design
| Feature | *args | **kwargs |
|---|---|---|
| Arguments collected | Extra positional arguments | Keyword arguments |
| Container inside the function | Tuple | Dictionary |
| How values are supplied | By position | By name and value |
| Useful iteration target | Each tuple item | Dictionary entries or values |
Both forms collect a variable number of inputs, but they preserve different kinds of argument information.
Variable arguments are useful when the function genuinely does not know how many arguments it will receive. Appropriate uses include aggregation such as summing, averaging, or concatenating data; optional configuration parameters; and functions that wrap other functions. If a function always expects a specific number of arguments, define those parameters explicitly. Explicit parameters make the function clearer and help catch mistakes earlier.
Mistakes with Variable Arguments
Common mistake Putting parameters in the wrong order.
What it looks likedef total(*numbers, initial, **keywords):Why it failsThe required order is fixed parameters, then *args, then **kwargs. Python enforces this order.
Do this insteadPlace initial first, numbers second, and keywords last: def total(initial, *numbers, **keywords):
Common mistake Treating *args as one individual value instead of a tuple.
What it looks likeA function receives 1, 2, and 3, but processes numbers as though it were one number.
Why it fails*args collects the extra positional arguments into a tuple, so the function must process the tuple's items.
Do this insteadIterate over numbers to process each collected positional value.
Common mistake Treating **kwargs as a single value instead of a dictionary.
What it looks likeA function receives vegetables=50 and fruits=100, but ignores the key-value structure.
Why it fails**kwargs collects the keyword arguments into a dictionary.
Do this insteadIterate over the dictionary or its values to process the supplied keyword arguments.
Common mistake Using variable arguments when the number of inputs is always known.
What it looks likeUsing *args for a function that always requires exactly three specific inputs.
Why it failsVariable arguments can make a function less clear when its input count is already fixed.
Do this insteadDefine the expected parameters explicitly.
Practice the Argument Flow
Write a function named total_values that accepts an initial value, any number of extra positional numbers, and any number of keyword values. Start with the initial value, add every value from the positional tuple, then add every value from the keyword dictionary. Test it with total_values(5, 2, 3, apples=4, oranges=6). Predict the result before running the function.
Hints
- Put the fixed initial parameter before *numbers and **keywords.
- Use one loop for the values collected by *numbers.
- Use a second loop for the values collected by **keywords.
- 1Variable argument lists let one function accept an unknown number of inputs. Extra positional arguments collected with *args become a tuple, while keyword arguments collected with **kwargs become a dictionary. Both collections can be iterated over inside the function. Keep the parameter order fixed: regular parameters first, *args next, and **kwargs last. Use this flexibility when the number of inputs is genuinely variable, but prefer explicit parameters when the function's inputs are always known.
Key Takeaways
- *args collects extra positional arguments into a tuple.
- **kwargs collects keyword arguments into a dictionary.
- Both collections can be iterated over like ordinary tuples and dictionaries.
- The required parameter order is fixed parameters, then *args, then **kwargs.
- Variable arguments are most useful when the number of inputs is unknown at definition time.