6 个 Python 中使用 * 和 ** 的场景
通过示例解释
如果你曾经阅读过Python库的文档,那么你一定会注意到在几个地方使用了*或**。
但是,它们(*和**)是做什么用的呢?
我们将学习7个使用*和**的例子,包括你在文档中注意到的案例。
使用示例来解释这些用例是最好的,所以让我们直接开始吧。
1. 使用可迭代对象调用函数
假设你定义了一个函数,它需要5个位置参数,将它们相加并返回总和。
# 定义函数def calculate_sum(a, b, c, d, e): return a + b + c + d + e# 调用函数result = calculate_sum(1, 4, 3, 2, 6)print(result)16
如果作为参数传递给函数的值存储在一个可迭代对象(例如列表)中,你可以直接使用列表调用函数,但是你需要使用*,如下所示:
# 调用函数numbers = [1, 4, 3, 2, 6]calculate_sum(*numbers)print(result)16
如果尝试像calculate_sum(numbers)
这样调用函数,Python会报错,引发TypeError
。这里*的作用是解包可迭代对象中的值,有时也称为参数解包。
需要注意的是,numbers
列表中的值的数量必须等于函数所需的参数数量,这在这种情况下是5。否则,我们会得到TypeError
。
2. 使用字典调用函数
这个用例与前一个用例类似。在前一个示例中,函数只有位置参数。对于带有关键字参数的函数,我们仍然可以进行参数解包,但是使用**而不是*。
# 定义函数def calculate_mass(density, length=1, width=1, height=1): return density * length * width * height# 调用函数density = 20mass = calculate_mass(density, 2, 3, 5)print(mass)600
该函数使用密度、长度、宽度和高度计算物体的质量。假设这些测量值存储在Python字典中。我们可以直接使用字典调用函数,如下所示:
# 调用函数density = 20measures = { "length": 2, "width": 3, "height": 5}calculate_mass(density, **measures)600
与第一个示例类似,如果我们尝试像calculate_mass(density, measures)
这样调用它,我们会得到TypeError
。这是另一个参数解包的示例。
3. 定义一个带有任意数量位置参数的函数
你定义了一个函数,它将给定的值相加,但是你不想对传递的值的数量施加限制。相反,你希望它是动态的,并且可以总结任意数量的给定值。
下面是我们如何定义这个函数:
# 定义函数def calculate_sum(*args): result = 0 for i in args: result += i return result
*args
表达式将传递给函数的参数打包,允许我们使用任意数量的参数或可迭代对象调用该函数。
下面是不同调用这个函数的方法:
# 调用2个值的情况calculate_sum(3, 4)7# 调用一个列表的情况my_list = [1, 4, 5, 10, 20]calculate_sum(*my_list)40# 调用一个值和一个列表的情况my_list = [10, 20, 30]calculate_sum(5, *my_list)65
如果使用可迭代对象调用函数,则在调用函数时仍需要放置 *。
关于位置参数和关键字参数的说明:
位置参数仅通过名称声明。调用函数时,必须为位置参数提供值。否则,将会出现错误。
关键字参数通过名称和默认值声明。如果我们没有为关键字参数指定值,则它将取默认值。
4. 定义带有任意数量关键字参数的函数
这个与前一个用例类似,但我们将创建一个接受关键字参数的函数。
# 定义函数def greet(name, **kwargs): greeting = f"Hello, {name}.\n" if kwargs: greeting += "Here are the things I know about you:\n" for key, value in kwargs.items(): greeting += f" {key.title()}: {value}\n" return greeting
函数通过给定名称来问候人们。如果使用关于人们的其他关键字参数调用它,则函数也会将它们打印出来。
**kwargs
表达式允许我们在调用函数时传递任意数量的关键字参数。
以下是调用此函数的不同方式:
# 仅使用名称(位置参数)调用print(greet("John"))# 输出Hello, John.# 添加一些关键字参数调用print(greet("Jane", age=34, job="doctor", hobby="chess"))# 输出Hello, Jane.Here are the things I know about you: Age: 34 Job: doctor Hobby: chess# 将一些关键字参数作为字典添加进行调用ashley = { "age": 27, "profession": "athlete", "hobby": "reading"}print(greet("Ashley", **ashley))# 输出Hello, Ashley.Here are the things I know about you: Age: 27 Profession: athlete Hobby: reading
如果将关键字参数作为字典传递,则在调用函数时需要放置 **。
5. 合并字典
我们可以使用 ** 来合并字典。
ages = { "John": 34, "Jane": 36}new_items = { "Matt": 28, "Ashley": 24}ages = {**ages, **new_items}print(ages){'John': 34, 'Jane': 36, 'Matt': 28, 'Ashley': 24}
在这种情况下,使用 ages = {ages, new_items}
同样会引发 TypeError
。
6. 将值打包到可迭代对象中
假设我们有一个包含多个值的列表。我们想要将该列表中的一个值分配给另一个变量,并将剩余的值分配给另一个变量。当我们通过以下示例进行演示时,它将更加清晰:
first, *others = [3, 5, 1, 10, 24]print(first)print(others)# 输出3[5, 1, 10, 24]
第一个值分配给名为 first
的变量,其余的值打包到名为 others
的另一个列表中。
我们也可以像下面的示例一样使用它:
first, *others, last = [3, 5, 1, 10, 24]print(first)print(others)print(last)# 输出3[5, 1, 10]24
当使用返回多个值的函数时,这个用例可能会很有帮助。以下是一个示例:
# 定义函数def my_func(a, b, c, d, e): sum_1 = a + b sum_2 = a + b + c sum_3 = a + b + c + d sum_4 = a + b + c + d + e return sum_1, sum_2, sum_3, sum_4# 调用函数first_sum, *other_sums = my_func(1, 3, 5, 2, 6)print(first_sum)print(other_sums)# 输出4[9, 11, 17]
my_func
函数返回一个包含 4 个值的元组。第一个值被赋值给变量 first_one
,其他的值被赋值给名为 other_sums
的列表。
最后的话
正如我们所演示的例子,* 和 ** 在 Python 中非常有用。我们可以使用它们进行参数打包和解包。
它们还用于定义和调用函数,以增加更多的灵活性和多样性。
您可以成为小猪AI的会员,以解锁我所有的文章,以及小猪AI的其他内容。如果您已经是会员,请订阅,以便在我发布新文章时收到电子邮件。
感谢您的阅读。如果您有任何反馈,请告诉我。