🐍 Python Q13 / 170

What is *args and **kwargs?

AI-Powered Answer ✓ Answered

In Python, *args and **kwargs are special syntaxes used in function definitions to pass a variable number of arguments to a function. They provide flexibility, allowing functions to accept any number of non-keyword and keyword arguments, respectively.

*args (Non-Keyword Arguments)

The *args syntax allows a function to accept a variable number of non-keyword arguments. When used as a parameter, *args collects all positional arguments passed to the function into a tuple. The asterisk (*) unpacks an iterable (like a list or tuple) when calling a function, passing its elements as individual positional arguments.

python
def my_sum(*args):
    result = 0
    for x in args:
        result += x
    return result

print(my_sum(1, 2, 3))
# Output: 6

print(my_sum(10, 20, 30, 40))
# Output: 100

my_list = [5, 6, 7]
print(my_sum(*my_list))
# Output: 18

The name args is merely a convention; you could use *numbers or *items, but *args is widely accepted and recommended for readability.

**kwargs (Keyword Arguments)

The kwargs syntax allows a function to accept a variable number of keyword arguments. When used as a parameter, kwargs collects all keyword arguments passed to the function into a dictionary, where the keys are the argument names and the values are their corresponding values. The double asterisk (**) unpacks a dictionary when calling a function, passing its key-value pairs as keyword arguments.

python
def greet_person(**kwargs):
    if 'name' in kwargs and 'greeting' in kwargs:
        print(f"{kwargs['greeting']}, {kwargs['name']}!")
    elif 'name' in kwargs:
        print(f"Hello, {kwargs['name']}!")
    else:
        print("Hello there!")

greet_person(name="Alice", greeting="Hi")
# Output: Hi, Alice!

greet_person(name="Bob")
# Output: Hello, Bob!

my_dict = {'name': 'Charlie', 'age': 30}
greet_person(**my_dict)
# Output: Hello, Charlie!

Similar to *args, the name kwargs is a convention. You could use data or options, but **kwargs is the standard.

Combining *args and **kwargs

It's common to use both *args and **kwargs in the same function definition. When doing so, there's a specific order that must be followed:

  • Standard positional arguments
  • Standard keyword arguments
  • *args
  • **kwargs
python
def combined_example(fixed_arg, *args, default_kwarg='default', **kwargs):
    print(f"Fixed Argument: {fixed_arg}")
    print(f"Positional Arguments (*args): {args}")
    print(f"Default Keyword Argument: {default_kwarg}")
    print(f"Keyword Arguments (**kwargs): {kwargs}")

combined_example(10, 20, 30, default_kwarg='custom', key1='value1', key2='value2')
# Output:
# Fixed Argument: 10
# Positional Arguments (*args): (20, 30)
# Default Keyword Argument: custom
# Keyword Arguments (**kwargs): {'key1': 'value1', 'key2': 'value2'}

combined_example('start', 'middle', 'end', extra=True)
# Output:
# Fixed Argument: start
# Positional Arguments (*args): ('middle', 'end')
# Default Keyword Argument: default
# Keyword Arguments (**kwargs): {'extra': True}

Key Takeaways

  • *args collects an arbitrary number of non-keyword (positional) arguments into a tuple.
  • **kwargs collects an arbitrary number of keyword arguments into a dictionary.
  • They enhance function flexibility, allowing them to handle varying argument lists without explicit parameter declarations.
  • The unpacking operators * and ** can also be used when *calling* a function to expand iterables (for *args) or dictionaries (for **kwargs) into individual arguments.