在函数调用中,*和**这两个操作符分别代表什么意思?
在函数调用中,*和**这两个操作符分别代表什么意思?
在类似于zip(*x)
或f(**k)
的代码中,*
和 **
各自代表什么意思?Python是如何实现这种行为,并且对性能有哪些影响?
请参阅:将元组展开为参数。请使用该链接关闭问题,其中OP需要在参数上使用*
,但并不知道它的存在。
请参阅关于参数,**(双星号/星号)和 *(星号/星号)的作用?以了解有关参数的补充问题。
在函数调用中,单个星号将列表转换为单独的参数(例如,若已知 x=[x1,x2,x3]
,则zip(*x)
的结果与 zip(x1, x2, x3)
相同),而双星号将字典转换为独立的关键字参数(例如f(**k)
的结果与f(x=my_x, y=my_y)
相同,其中 k = {'x':my_x, 'y':my_y}
)。
在函数定义中,情况相反:单个星号将任意数量的参数转换为列表,而双星号将任意数量的关键字参数转换为字典。例如def foo(*x)
表示“foo接受任意数量的参数,并可以通过x
来访问它们(即如果用户调用foo(1,2,3)
,则x
将是(1,2,3)
)”,而def bar(**k)
则表示“bar 接受任意数量的关键字参数并且可以通过k
来访问它们(即如果用户调用bar(x=42, y=23)
,则k
将是{'x': 42, 'y': 23}
)”。
单个星号*
可以将序列或集合解包为位置参数。假设我们有
def add(a, b): return a + b values = (1, 2)
使用解包运算符*
,我们可以编写s = add(*values)
,它等同于编写s = add(1, 2)
。
双星号**
对于字典执行相同的操作,为命名参数提供值:
values = { 'a': 1, 'b': 2 } s = add(**values) # equivalent to add(a=1, b=2)
两个运算符都可以用于同一个函数调用。例如,给定:
def sum(a, b, c, d): return a + b + c + d values1 = (1, 2) values2 = { 'c': 10, 'd': 15 }
那么s = add(*values1, **values2)
等同于s = sum(1, 2, c=10, d=15)
。
请参阅Python文档中的相关部分。
同样,*
和**
也可用于参数。使用*
允许函数接受任何数量的位置参数,这些参数将被收集到单个参数中:
def add(*values): s = 0 for v in values: s = s + v return s
现在当函数像s = add(1, 2, 3, 4, 5)
这样调用时,values
将是元组(1, 2, 3, 4, 5)
(当然,这产生结果15
)。
类似地,标有**
的参数将接收一个dict
:
def get_a(**values): return values['a'] s = get_a(a=1, b=2) # returns 1
这允许指定大量可选参数而无需声明它们。
同样,两者可以结合使用:
def add(*values, **options): s = 0 for i in values: s = s + i if "neg" in options: if options["neg"]: s = -s return s s = add(1, 2, 3, 4, 5) # returns 15 s = add(1, 2, 3, 4, 5, neg=True) # returns -15 s = add(1, 2, 3, 4, 5, neg=False) # returns 15