Python tutorials > Core Python Fundamentals > Functions > How to use `*args` and `**kwargs`?
How to use `*args` and `**kwargs`?
In Python, *args
and **kwargs
are powerful tools that allow you to create functions that can accept a variable number of arguments. They provide flexibility and make your functions more adaptable to different situations.
Understanding `*args`
*args
allows a function to accept any number of positional arguments. It collects these arguments into a tuple within the function. The name args
is just a convention; you could technically use any valid variable name, but args
is widely accepted and improves readability. The key element is the single asterisk (*
) before the variable name.
Example of `*args` in Action
In this example, my_sum
can take any number of numerical arguments. Inside the function, args
becomes a tuple containing all the arguments passed. We iterate through this tuple and sum the elements.
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(4, 5, 6, 7)) # Output: 22
print(my_sum()) # Output: 0
Understanding `**kwargs`
**kwargs
allows a function to accept any number of keyword arguments (arguments passed with a name). It collects these arguments into a dictionary within the function. Similar to args
, the name kwargs
is a convention, but the double asterisk (**
) is crucial. The keys of the dictionary are the names of the keyword arguments, and the values are their respective values.
Example of `**kwargs` in Action
In this example, introduce
can take any number of keyword arguments. Inside the function, kwargs
becomes a dictionary. We iterate through the dictionary using .items()
to access both the keys (argument names) and values.
def introduce(**kwargs):
for key, value in kwargs.items():
print(f"{key} is {value}")
introduce(name="Alice", age=30, city="New York")
# Output:
# name is Alice
# age is 30
# city is New York
Combining `*args` and `**kwargs`
You can use both The output will be:*args
and **kwargs
in the same function definition. When you do, *args
must come before **kwargs
in the function signature. This ensures that positional arguments are correctly captured before keyword arguments.Positional arguments (args):
1
2
3
Keyword arguments (kwargs):
name: Bob
age: 40
def my_function(*args, **kwargs):
print("Positional arguments (args):")
for arg in args:
print(arg)
print("\nKeyword arguments (kwargs):")
for key, value in kwargs.items():
print(f"{key}: {value}")
my_function(1, 2, 3, name="Bob", age=40)
Concepts Behind the Snippet
The core concept behind *args
and **kwargs
is parameter unpacking. *
unpacks iterables (like lists or tuples) into positional arguments, while **
unpacks dictionaries into keyword arguments. They enhance code reusability and flexibility by allowing functions to adapt to varying input structures.
Real-Life Use Case
Consider a function that calculates the average of a variable number of numbers. Using In the example:*args
lets the function handle any quantity of numbers passed to it. We also incorporated the precision of the result with kwargs for a default value.
def calculate_average(*numbers, precision=2):
if not numbers:
return 0.0 # Avoid division by zero
total = sum(numbers)
average = total / len(numbers)
return round(average, precision)
print(calculate_average(10, 20, 30))
print(calculate_average(10, 20, 30, 40, precision=3)) #specify a kwarg
Best Practices
args
and kwargs
are common, choose names that reflect the purpose of the arguments if possible.*args
and **kwargs
can make your code harder to understand. Consider whether a more explicit function signature would be clearer.
Interview Tip
During an interview, be prepared to explain not just how *args
and **kwargs
work, but also why you would choose to use them. Emphasize the flexibility and adaptability they provide, and be able to discuss scenarios where they would be particularly useful. Also, explain when not to use them (e.g., when the number and type of arguments are well-defined and unlikely to change).
When to use them
Use *args
and **kwargs
when:
Memory Footprint
*args
creates a tuple, and **kwargs
creates a dictionary. These data structures consume memory, so passing extremely large numbers of arguments could potentially impact performance, especially if these arguments are large objects. However, for most common use cases, the memory overhead is negligible.
Alternatives
Alternatives to using *args
and **kwargs
:argparse
provide more advanced argument parsing capabilities.
Pros
Cons
FAQ
-
What's the difference between `*args` and `**kwargs`?
*args
collects positional arguments into a tuple, while**kwargs
collects keyword arguments into a dictionary. -
Do I have to name them `args` and `kwargs`?
No, the names
args
andkwargs
are just conventions. The important part is the single asterisk (*
) for positional arguments and the double asterisk (**
) for keyword arguments. -
Can I use them in any function?
Yes, you can use them in any function definition. Just remember that
*args
must come before**kwargs
in the function signature. -
When should I use specific parameters instead of *args or **kwargs?
Use specific parameters when the number and type of arguments are well-defined and unlikely to change. This improves code clarity and type safety.