在函数调用中,*和**这两个操作符分别代表什么意思?

45 浏览
0 Comments

在函数调用中,*和**这两个操作符分别代表什么意思?

在类似于zip(*x)f(**k)的代码中,*** 各自代表什么意思?Python是如何实现这种行为,并且对性能有哪些影响?


请参阅:将元组展开为参数。请使用该链接关闭问题,其中OP需要在参数上使用*,但并不知道它的存在。

请参阅关于参数,**(双星号/星号)和 *(星号/星号)的作用?以了解有关参数的补充问题。

admin 更改状态以发布 2023年5月21日
0
0 Comments

在函数调用中,单个星号将列表转换为单独的参数(例如,若已知 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})”。

0
0 Comments

单个星号*可以将序列或集合解包为位置参数。假设我们有

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

0