*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
*args和**kwargs是什么意思?
def foo(x, y, *args):
def bar(x, y, **kwargs):
当前回答
*表示以元组形式接收变量参数
**表示接收变量参数作为字典
使用方式如下:
1) 单个*
def foo(*args):
for arg in args:
print(arg)
foo("two", 3)
输出:
two
3
2) 现在**
def bar(**kwargs):
for key in kwargs:
print(key, kwargs[key])
bar(dic1="two", dic2=3)
输出:
dic1 two
dic2 3
其他回答
给定一个有3项作为参数的函数
sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items
sum([1,2,3]) # error, needs 3 items, not 1 list
x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok
sum(*[1,2,3]) # ok, 1 list becomes 3 items
想象一下这个玩具有一个三角形、一个圆形和一个长方形的袋子。那个包不太合身。你需要打开袋子,取出这3件物品,现在它们就可以了。Python*运算符执行此解包过程。
单*表示可以有任意数量的额外位置参数。foo()可以像foo(1,2,3,4,5)一样调用。在foo()的主体中,param2是一个包含2-5的序列。
双**表示可以有任意数量的额外命名参数。bar()可以像bar(1,a=2,b=3)一样调用。在bar()的主体中,param2是一个字典,其中包含{‘a‘:2,‘b‘:3}
使用以下代码:
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
foo(1,2,3,4,5)
bar(1,a=2,b=3)
输出为
1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
在Python 3.5中,您还可以在列表、字典、元组和集合显示(有时也称为文字)中使用此语法。参见PEP 488:其他解包概括。
>>> (0, *range(1, 4), 5, *range(6, 8))
(0, 1, 2, 3, 5, 6, 7)
>>> [0, *range(1, 4), 5, *range(6, 8)]
[0, 1, 2, 3, 5, 6, 7]
>>> {0, *range(1, 4), 5, *range(6, 8)}
{0, 1, 2, 3, 5, 6, 7}
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> e = {'six': 6, 'seven': 7}
>>> {'zero': 0, **d, 'five': 5, **e}
{'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}
它还允许在单个函数调用中解包多个可迭代项。
>>> range(*[1, 10], *[2])
range(1, 10, 2)
(感谢mgilson提供PEP链接。)
我想举一个别人没有提到的例子
*也可以打开发电机
Python3文档中的示例
x = [1, 2, 3]
y = [4, 5, 6]
unzip_x, unzip_y = zip(*zip(x, y))
unzip x将为(1,2,3),unzip y将为(4,5,6)
zip()接收多个iretable参数,并返回一个生成器。
zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))
让我们首先了解什么是位置参数和关键字参数。下面是带有位置参数的函数定义示例。
def test(a,b,c):
print(a)
print(b)
print(c)
test(1,2,3)
#output:
1
2
3
这是一个带有位置参数的函数定义。也可以使用关键字/命名参数调用它:
def test(a,b,c):
print(a)
print(b)
print(c)
test(a=1,b=2,c=3)
#output:
1
2
3
现在让我们研究一个带有关键字参数的函数定义示例:
def test(a=0,b=0,c=0):
print(a)
print(b)
print(c)
print('-------------------------')
test(a=1,b=2,c=3)
#output :
1
2
3
-------------------------
也可以使用位置参数调用此函数:
def test(a=0,b=0,c=0):
print(a)
print(b)
print(c)
print('-------------------------')
test(1,2,3)
# output :
1
2
3
---------------------------------
所以我们现在知道了带有位置参数和关键字参数的函数定义。
现在让我们研究一下“*”运算符和“**”运算符。
请注意,这些运算符可用于两个区域:
a) 函数调用
b) 函数定义
在函数调用中使用“*”运算符和“**”运算符。
让我们直接讲一个例子,然后讨论它。
def sum(a,b): #receive args from function calls as sum(1,2) or sum(a=1,b=2)
print(a+b)
my_tuple = (1,2)
my_list = [1,2]
my_dict = {'a':1,'b':2}
# Let us unpack data structure of list or tuple or dict into arguments with help of '*' operator
sum(*my_tuple) # becomes same as sum(1,2) after unpacking my_tuple with '*'
sum(*my_list) # becomes same as sum(1,2) after unpacking my_list with '*'
sum(**my_dict) # becomes same as sum(a=1,b=2) after unpacking by '**'
# output is 3 in all three calls to sum function.
所以记住
在函数调用中使用“*”或“**”运算符时-
“*”运算符将列表或元组等数据结构解包为函数定义所需的参数。
“**”运算符将字典解包为函数定义所需的参数。
现在让我们研究函数定义中使用的“*”运算符。例子:
def sum(*args): #pack the received positional args into data structure of tuple. after applying '*' - def sum((1,2,3,4))
sum = 0
for a in args:
sum+=a
print(sum)
sum(1,2,3,4) #positional args sent to function sum
#output:
10
在函数定义中,“*”运算符将收到的参数打包到一个元组中。
现在让我们看看函数定义中使用的“**”示例:
def sum(**args): #pack keyword args into datastructure of dict after applying '**' - def sum({a:1,b:2,c:3,d:4})
sum=0
for k,v in args.items():
sum+=v
print(sum)
sum(a=1,b=2,c=3,d=4) #positional args sent to function sum
在函数定义中,“**”运算符将收到的参数打包到字典中。
所以请记住:
在函数调用中,“*”将元组或列表的数据结构解包为要由函数定义接收的位置或关键字参数。
在函数调用中,“**”将字典的数据结构解包为函数定义要接收的位置或关键字参数。
在函数定义中,“*”将位置参数打包到元组中。
在函数定义中,“**”将关键字参数打包到字典中。