Hello everyone, if you can create functions that adapt to different scenarios in Python without rewriting them every time, it will make the operation simple and convenient. This is the magic of *args and **kwargs. It's like preparing a magic bag for a function that can hold as many parameters as you like - making the code cleaner and more flexible.
To help everyone better understand *args and **kwargs in Python, let’s show what state the code will be if these concepts are not available.
Here is a simple function simple_sum, which is used to add two numbers:
def simple_sum(a, b): return a + b result = simple_sum(3, 7) print(result)
Imagine if you want to create a function that adds three numbers, you might end up rewriting this function in the following way:
def simple_sum_three(a, b, c): return a + b + c result_three = simple_sum_three(3, 7, 5) print(result_three)
If you want to add more numbers, you have to create new functions for each case, which is neither elegant nor flexible. To solve this problem, there is a concept called "parameter packaging", which can use the * symbol in a function definition statement, convert a parameter into a super parameter, which can act as a bag and hold/pack to pass all its values when calling the function, stored in a variable.
Similarly, symbol * can also be used to unpack data structures, depending on how it is used, which will be described later in this article.
1. Use *args for parameter packaging
In Python, when you see an asterisk (*) in the function definition immediately before a parameter, this is the signal for parameter packing. This means that any number of parameters can be passed to the function and they will be neatly packaged into a tuple. It's like having a magic bag for a function that allows it to adapt to different situations without having to constantly rewrite the function.
def magic_sum(*args): result = sum(args) return result # Add up three numbersresult1 = magic_sum(3, 7, 5) print("Result 1:", result1) # Expected output: 15 (3+7+5) # Add up five numbersresult2 = magic_sum(1, 2, 3, 4, 5) print("Result 2:", result2) # Expected output: 15 (1+2+3+4+5) # Add more numbersresult3 = magic_sum(10, 20, 30, 40, 50, 60) print("Result 3:", result3) # Expected output: 210 (10+20+30+40+50+60)
In this example, the magic_sum function uses *args for parameter packing. This function can be called with different numbers of parameters, which will neatly package these parameters into a tuple for addition. In this case, the variable args becomes a tuple. It's like having a calculator that can handle any number of inputs without changing its formula.
2. Parameter unpacking
On the other hand, when calling a function, an asterisk (*) can be used to indicate that a sequence of values (tuples, lists, collections, strings) is being unpacked and its elements are passed as separate values. This approach is suitable for cases where data is saved in a collection (such as a tuple), but you want to extract each value from the collection and pass it to a function as a separate parameter.
def display_values(a, b, c): print("Value of a:", a) print("Value of b:", b) print("Value of c:", c) # Unpack a tuple and pass its elements as separate valuestuple_values = (7, 14, 21) display_values(*tuple_values) # is equivalent to display_values(7, 14, 21)
This method can be used to extract values from multiple collection type data:
def display_values(a, b, c): print("Value of a:", a) print("Value of b:", b) print("Value of c:", c) # Unpack a tuple and pass its elements as separate valuestuple_values = (7, 14, 21) display_values(*tuple_values) # is equivalent to display_values(7, 14, 21) # Unpack a listlist_values = [30, 40, 50] display_values(*list_values) # is equivalent to display_values(30, 40, 50) # Unpack a string (each character becomes a separate parameter)string_values = "XYZ" display_values(*string_values) # is equivalent to display_values('X', 'Y', 'Z') # Unpack a collectionset_values = {60, 70, 80} display_values(*set_values) # The order may change, equivalent to display_values(60, 70, 80) # Unpack a scoperange_values = range(3, 6) display_values(*range_values) # Equivalent to display_values(3, 4, 5)
You can also change a, b, and c of the function definition part to values to receive a variable number of parameters. values will become a tuple of all parameters passed. This can be understood as simultaneous packaging and unpacking.
def display_values(*values): # Package the value into a variable. print("Values:", values) # Unpack a tuple and pass its elements as separate valuestuple_values = (7, 14, 21) display_values(*tuple_values)
3. Use ** to package keyword parameters
Next, this article will use the double asterisk (**), an operator in Python that brings the packaging and unpacking of dictionaries into it. When a function parameter is prefixed with "**", it means that the corresponding parameter should be a key-value pair and is neatly packaged into a dictionary. This is the same as the package of tuple parameters, but is used in cases where the function parameters are keyword parameters.
def display_info(**kwargs): for key, value in (): print(f"{key}: {value}") # Pass keyword parameters directly in function callsdisplay_info(name='Alice', age=25, city='Wonderland')
4. Unpacking keyword parameters
Unpack the dictionary and pass its contents to the function as a separate keyword argument. This approach is suitable for situations where data is saved in a dictionary, but want to extract each key-value pair from the dictionary and pass it to the function as a separate keyword argument:
def display_person_info(name, age, city): print("Name:", name) print("Age:", age) print("City:", city) # Unpack a dictionary containing expected key-value pairsperson_info = {'name': 'Alice', 'age': 25, 'city': 'Wonderland'} display_person_info(**person_info)
5. Use *args and **kwargs in combination
Combining the power of *args and **kwargs, treat them as positional parameter lists and keyword parameter lists with variable length, respectively.
def display_information(*args, **kwargs): print("Positional Arguments (*args):") for arg in args: print(arg) print("\nKeyword Arguments (**kwargs):") for key, value in (): print(f"{key}: {value}") # Call functions using a mixed positional parameter and keyword parameterdisplay_information(1, 'apple', name='Alice', age=25, city='Wonderland')
In this example, the display_information function receives *args to process any number of positional parameters, and **kwargs to process any number of keyword parameters, and the function then prints each type of parameters separately.
6. Depack multiple times at once
Another interesting feature in Python is the ability to perform multiple unpacking in a single function call.
def display_values(*args): for value in args: print(value) # Depack multiple times in a single function calllist_values = [1, 2, 3] tuple_values = (4, 5, 6) set_values = {7, 8, 9} display_values(*list_values, *tuple_values, *set_values)
In this example, the display_values function calls three different iterable types (list, tuple, and collection) in a single line using multiple unpacking. During function calls, all values are collected by multiple unpacking (*list_values, *tuple_values, *set_values) and stored in a single args parameter.
This is the article about this article that will lead you to master the application skills of *args and **kwargs in Python. For more related Python *args **kwargs content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!