#1 Data Analytics Program in India
₹2,499₹1,499Enroll Now
6 min read
•Question 23 of 41medium

*args and **kwargs

Variable-length arguments in Python.

What You'll Learn

  • What *args and **kwargs are
  • When and how to use them
  • Function parameter ordering rules
  • Unpacking arguments when calling functions
  • Real-world use cases

Understanding *args

*args allows a function to accept any number of positional arguments. Inside the function, args is a tuple.

code.pyPython
def sum_all(*args):
    print(f"args is a tuple: {type(args)}")  # <class 'tuple'>
    print(f"Received: {args}")
    return sum(args)

print(sum_all(1, 2, 3))          # 6
print(sum_all(1, 2, 3, 4, 5))    # 15
print(sum_all())                  # 0 (empty tuple)

# Iterate over args
def print_numbered(*args):
    for i, arg in enumerate(args, 1):
        print(f"{i}. {arg}")

print_numbered("apple", "banana", "cherry")
# 1. apple
# 2. banana
# 3. cherry

Understanding **kwargs

**kwargs allows a function to accept any number of keyword arguments. Inside the function, kwargs is a dictionary.

code.pyPython
def print_info(**kwargs):
    print(f"kwargs is a dict: {type(kwargs)}")  # <class 'dict'>
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="NYC")
# name: Alice
# age: 30
# city: NYC

# With default handling
def create_user(**kwargs):
    return {
        "name": kwargs.get("name", "Anonymous"),
        "role": kwargs.get("role", "user"),
        "active": kwargs.get("active", True)
    }

user = create_user(name="Bob", role="admin")
print(user)  # {'name': 'Bob', 'role': 'admin', 'active': True}

Parameter Order Rules

Python requires parameters in this specific order:

code.pyPython
def func(
    positional,           # 1. Regular positional
    *args,                # 2. *args
    keyword_only,         # 3. Keyword-only (after *)
    **kwargs              # 4. **kwargs (always last)
):
    pass

# Complete example
def example(a, b, *args, option=True, **kwargs):
    print(f"a={a}, b={b}")
    print(f"args={args}")
    print(f"option={option}")
    print(f"kwargs={kwargs}")

example(1, 2, 3, 4, option=False, x=10, y=20)
# a=1, b=2
# args=(3, 4)
# option=False
# kwargs={'x': 10, 'y': 20}

Unpacking Arguments

Use * and ** when calling functions to unpack sequences and dictionaries:

code.pyPython
def greet(name, greeting, punctuation):
    return f"{greeting}, {name}{punctuation}"

# Unpack list/tuple with *
args = ["Alice", "Hello", "!"]
print(greet(*args))  # "Hello, Alice!"

# Unpack dict with **
kwargs = {"name": "Bob", "greeting": "Hi", "punctuation": "?"}
print(greet(**kwargs))  # "Hi, Bob?"

# Combine both
data = ["Charlie"]
options = {"greeting": "Hey", "punctuation": "."}
print(greet(*data, **options))  # "Hey, Charlie."

Forwarding Arguments

A common pattern for wrapper functions:

code.pyPython
def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        print(f"  args: {args}")
        print(f"  kwargs: {kwargs}")
        return func(*args, **kwargs)  # Forward all arguments
    return wrapper

@log_call
def calculate(a, b, operation="add"):
    if operation == "add":
        return a + b
    return a - b

calculate(5, 3, operation="subtract")
# Calling calculate
#   args: (5, 3)
#   kwargs: {'operation': 'subtract'}
# Returns: 2

Practical Use Cases

code.pyPython
# 1. Flexible initialization
class Config:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

config = Config(debug=True, host="localhost", port=8080)
print(config.debug)  # True

# 2. Merging dictionaries
def merge_dicts(*dicts):
    result = {}
    for d in dicts:
        result.update(d)
    return result

combined = merge_dicts({"a": 1}, {"b": 2}, {"c": 3})
print(combined)  # {'a': 1, 'b': 2, 'c': 3}

# 3. String formatting
template = "Name: {name}, Age: {age}"
data = {"name": "Alice", "age": 30}
print(template.format(**data))  # "Name: Alice, Age: 30"

Interview Tip

When asked about *args and **kwargs:

  1. *args → tuple of positional arguments
  2. **kwargs → dict of keyword arguments
  3. Order: positional, *args, keyword-only, **kwargs
  4. Use * and ** for unpacking when calling functions
  5. Common in decorators and wrapper functions