Understanding *args and **kwargs in Python: Variable-Length Arguments Explained with Examples

A fundamental function definition in Python requires a fixed number of parameters:

def add(x, y):
    return x + y

print(add(1, 2))  # Output: 3

Here, x and y are positional parameters — you must pass exactly two arguments in order. But what happens when you need a function that can handle a varying number of arguments? This is common in many real-world scenarios, such as summing an arbitrary list of numbers.

Python solves this with two special argument types: variable positional arguments and variable keyword arguments.

Variable Positional Arguments: *args

When you prefix a parameter with a single asterisk (*), it becomes a variable positional argument. Although the conventional name is *args, you can use any valid identifier after the asterisk (e.g., *numbers). The key is the * symbol, not the name itself.

*args collects all extra positional arguments into a tuple. The function then iterates over this tuple to process the values.

Example: Summing an arbitrary count of numbers

def sum_values(*args):
    total = 0
    for val in args:
        total += val
    return total

print(sum_values(1, 3, 5))          # Output: 9
print(sum_values(2, 4, 6, 8))       # Output: 20

Here, sum_values can accept any number of positional arguments. The *args parameter bundles them into a tuple, and the loop accumulates the sum.

Variable Keyword Arguments: **kwargs

A parameter prefixed with two asterisks (**) is a variable keyword argument. By convention, this is named **kwargs. It collects all extra keyword arguments into a dictionary, where each key-value pair corresponds to a passed argument.

Example: Accepting arbitrary keyword parameters

def show_keyvals(**kwargs):
    print(kwargs)

show_keyvals(a=1, b=2, c=3)          # Output: {'a': 1, 'b': 2, 'c': 3}
show_keyvals(a=1, b=2, c=3, d=4)     # Output: {'a': 1, 'b': 2, 'c': 3, 'd': 4}

The function receives all keyword arguments as a dictionary. You can then acces values by their keys, iterate through items, or pass them to other functions.

Combining Fixed, *args, and **kwargs

You can mix regular parameters with *args and **kwargs in a single function, as long as they appear in the correct order:

  1. Standard posisional parameters
  2. *args
  3. Standard keyword-only parameters (not shown here)
  4. **kwargs
def total_score(base, *bonuses, **metadata):
    score = base
    for b in bonuses:
        score += b
    for key, val in metadata.items():
        print(f"{key}: {val}")
    return score

print(total_score(50, 10, 5, name="Alice", level="Expert"))

In this example, base is required, *bonuses picks up extra positional arguments as a tuple, and **metadata captures keyword arguments as a dictionary.

Practical Tips

  • Use *args when you expect a variable number of non-keyword arguments (common in decorators, logging, or mathematical functions).
  • Use **kwargs when you need to pass arbitrary named parameters (common in configuration, framework callbacks, or wrapping enother function).
  • The names args and kwargs are not enforced — you can use *foo and **bar. However, sticking to conventions improves readability.

Understanding *args and **kwargs is essential for writing flexible and reusable Python code. They allow functions to adapt to varying input without sacrificing clarity.

Tags: python args kwargs variable arguments function parameters

Posted on Mon, 01 Jun 2026 16:16:50 +0000 by ron814