Iterating Over Tuples and Dictionaries
Variable argument lists use * and ** syntax to bundle multiple arguments into a single parameter.
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)
Packing 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)
Tracing 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
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.
Fixed parameter: The first positional argument, 10, is assigned to initial.
Positional tuple: The remaining positional arguments are packed into numbers as (1, 2, 3).
Keyword dictionary: The named arguments are packed into keywords with entries for vegetables equal to 50 and fruits equal to 100.
Tuple iteration: The function processes 1, 2, and 3, changing the running total from 10 to 16.
Dictionary 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 |
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
Putting parameters in the wrong order.
The required order is fixed parameters, then *args, then **kwargs. Python enforces this order.
Fix:
Place initial first, numbers second, and keywords last: def total(initial, *numbers, **keywords):Treating *args as one individual value instead of a tuple.
*args collects the extra positional arguments into a tuple, so the function must process the tuple's items.
Fix:
Iterate over numbers to process each collected positional value.Treating **kwargs as a single value instead of a dictionary.
**kwargs collects the keyword arguments into a dictionary.
Fix:
Iterate over the dictionary or its values to process the supplied keyword arguments.Using variable arguments when the number of inputs is always known.
Variable arguments can make a function less clear when its input count is already fixed.
Fix:
Define 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.
- Variable 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.