🐶
Python

Python ** vs * Parameters: Usage and Examples

By Filip on 10/05/2024

Learn how single and double asterisks before parameters in Python functions provide flexibility for passing variable-length arguments and keyword arguments.

Python ** vs * Parameters: Usage and Examples

Table of Contents

Introduction

In Python, you can use single and double asterisks to make your functions more flexible by accepting a variable number of arguments. Let's explore how these special symbols work with function parameters.

Step-by-Step Guide

In Python, single and double asterisks have special meanings when used with function parameters.

A single asterisk (*) is used to pass a variable number of arguments to a function. These arguments are packed into a tuple.

For example:

def my_function(*args):
  for arg in args:
    print(arg)

my_function('hello', 10, True)

This code would print:

hello
10
True

On the other hand, a double asterisk (**) is used to pass a variable number of keyword arguments to a function. These arguments are packed into a dictionary.

For example:

def my_function(**kwargs):
  for key, value in kwargs.items():
    print(f"{key}: {value}")

my_function(name='Alice', age=30, city='New York')

This code would print:

name: Alice
age: 30
city: New York

In essence, *args allows you to input a flexible number of non-keyword arguments, while **kwargs allows a flexible number of keyword arguments (like those used in dictionaries) to be passed to your function.

Code Example

This Python code demonstrates the use of *args and **kwargs for passing a variable number of arguments to functions. It shows how to use *args to pass a variable number of positional arguments, **kwargs to pass a variable number of keyword arguments, and how to combine both in a single function. Each function includes basic printing to illustrate how the arguments are accessed within the function.

# Example using *args for variable number of arguments
def greet_people(*names):
  """Greets each person in the given list of names.
  """
  for name in names:
    print(f"Hello, {name}!")

greet_people("Alice", "Bob", "Charlie")

# Example using **kwargs for variable number of keyword arguments
def describe_person(name, **characteristics):
  """Prints a description of a person with given characteristics.
  """
  print(f"This is {name}.")
  for key, value in characteristics.items():
    print(f"{key}: {value}")

describe_person("Emily", age=25, occupation="Software Engineer", city="London")

# Example combining *args and **kwargs
def complex_function(arg1, arg2, *args, kwarg1="default", **kwargs):
  """Demonstrates a function using both *args and **kwargs.
  """
  print(f"Required arguments: {arg1}, {arg2}")
  print(f"Additional arguments: {args}")
  print(f"Keyword argument: {kwarg1}")
  print(f"Additional keyword arguments: {kwargs}")

complex_function(10, 20, "a", "b", "c", kwarg2="value2", kwarg3="value3")

This code demonstrates:

  1. *args: greet_people takes any number of names and greets each one.
  2. **kwargs: describe_person takes a name and any number of key-value pairs to describe the person.
  3. Combining *args and **kwargs: complex_function shows how to use both for maximum flexibility in function arguments.

This provides a clear and practical understanding of how single and double asterisks work in Python function parameters.

Additional Notes

  • Importance of Order: Remember that when defining function parameters, the order matters. It should be (normal_parameters, *args, **kwargs). You cannot deviate from this order.
  • Descriptive Naming: While *args and **kwargs are conventional, you can use other names like *numbers or **user_info. However, sticking to the convention improves code readability.
  • Use Cases:
    • *args: Useful when you need to pass a varying number of inputs to a function, like calculating the sum of any number of numbers.
    • **kwargs: Ideal for functions where you might have optional parameters, like setting configurations or options.
  • Unpacking Iterables: You can use * to unpack iterables (like lists or tuples) when passing them as arguments to a function. For example: my_function(*[1, 2, 3]) is equivalent to my_function(1, 2, 3).
  • Unpacking Dictionaries: Similarly, use ** to unpack dictionaries when passing them as keyword arguments: my_function(**{'name': 'Bob', 'age': 25}).
  • Advanced Use: *args and **kwargs are powerful tools for metaprogramming, allowing you to write functions that can handle a wide range of inputs and adapt to different situations.

Remember, using *args and **kwargs effectively can make your Python code more flexible, readable, and powerful.

Summary

Feature *args **kwargs
Purpose Pass a variable number of non-keyword arguments Pass a variable number of keyword arguments
Symbol Single asterisk (*) Double asterisk (**)
Data Type Packed into a tuple Packed into a dictionary
Example Usage def my_function(*args): def my_function(**kwargs):
Example Input my_function('hello', 10, True) my_function(name='Alice', age=30)

In short:

  • Use *args for flexibility in the number of positional arguments.
  • Use **kwargs for flexibility in the number of named arguments.

Conclusion

Understanding how to use *args and **kwargs provides you with powerful tools to make your functions more adaptable and dynamic. They are particularly useful when you need to handle a varying number of arguments, making your code more concise and efficient. By mastering these concepts, you'll be able to write more flexible and Pythonic code.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait