Python
function parameters
double asterisk
single asterisk
programming concepts

What does double star/asterisk and star/asterisk do for parameters?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In the world of programming, particularly in Python, the use of asterisks (*) and double asterisks (**) in function parameters serves a unique and useful purpose—allowing for flexible argument handling. This functionality is fundamental when dealing with functions that need to handle a large number of arguments or with arguments that may not all be known when writing the function.

The Single Asterisk: *

The single asterisk * is used in function definitions to allow for variable-length positional arguments. It collects all the positional arguments beyond the ones listed into a tuple. This is what is often referred to as "packing".

Using * for Variable-Length Positional Arguments

When a function parameter is prefixed with *, the function can accept any number of positional arguments. These arguments are packed into a tuple that the function can then process:

python
def print_names(*names):
    for name in names:
        print(name)

In this example, you can call print_names() with any number of arguments:

python
1print_names("Alice", "Bob", "Charlie")
2# Output:
3# Alice
4# Bob
5# Charlie

Unpacking with *

The * operator can also be used to unpack iterable objects into individual elements when passing arguments to a function:

python
1def sum_of_numbers(a, b, c):
2    return a + b + c
3
4numbers = (1, 2, 3)
5result = sum_of_numbers(*numbers)
6# result is 6

In this function call, the tuple numbers is unpacked into three positional arguments using the asterisk.

The Double Asterisk: **

The double asterisk ** is similarly invaluable when dealing with functions, but instead of positional arguments, it pertains to keyword arguments. It allows for packing and unpacking of dictionaries.

Using ** for Variable-Length Keyword Arguments

In a function definition, ** collects further keyword arguments into a dictionary:

python
def print_student_details(**details):
    for key, value in details.items():
        print(f"{key}: {value}")

This function can be called with any number of keyword arguments:

python
1print_student_details(name="Alice", age=25, grade="A")
2# Output:
3# name: Alice
4# age: 25
5# grade: A

Unpacking with **

Just as * unpacks a list or tuple, ** is used to unpack a dictionary into keyword arguments:

python
1def print_details(name, age):
2    print(f"Name: {name}, Age: {age}")
3
4student_info = {'name': 'Bob', 'age': 21}
5print_details(**student_info)
6# Output:
7# Name: Bob, Age: 21

Here, student_info is a dictionary that is unpacked into the name and age parameters.

Differences and Common Use-Cases

Feature* (Single Asterisk)** (Double Asterisk)
PurposeGathers positional arguments into a tupleGathers keyword arguments into a dictionary
Use CaseFlexible argument counts when the exact number isn’t known.Use when functions need to accept optional key-value pair arguments.
UnpackingUse *args to unpack sequencesUse **kwargs to unpack dictionary-like objects
Example Usagedef foo(*args): Used to iterate over argumentsdef bar(**kwargs): Handle named parameters as dictionary

Additional Considerations

Combining * and **

Functions can combine both *args and **kwargs to allow for handling positional as well as keyword arguments:

python
1def complex_function(*args, **kwargs):
2    print(f"Positional arguments: {args}")
3    print(f"Keyword arguments: {kwargs}")
4
5complex_function(1, 2, a="apple", b="banana")
6# Output:
7# Positional arguments: (1, 2)
8# Keyword arguments: {'a': 'apple', 'b': 'banana'}

Order of Parameters

When defining a function with both kinds of arguments, the order is critical: first, define standard positional arguments, followed by *args, standard keyword arguments, and finally **kwargs.

python
def ordered_function(a, b, *args, x=5, y=10, **kwargs):
    pass

Language Compatibility

While these concepts are especially prevalent in Python, many other programming languages offer similar functionality with variadic arguments. However, the specific syntax and semantics can differ significantly.

Conclusion

Understanding the use of * and ** in function parameters enhances the flexibility and robustness of your code. They enable functions to process an indeterminate number of inputs, making these functions highly reusable across various contexts. Once you become comfortable with these concepts, you will likely find yourself writing cleaner and more efficient code.


Course illustration
Course illustration

All Rights Reserved.