本文主要介绍了星号
*
在Python中一些常见的妙用。
函数不定长参数
在下面代码中,func2()
相当于是func()
的一个代理,那我们不想要每次func()
修改的时候,也跟着修改func2()
对应的参数,就可以用这种方式实现:
def func(a, b, c):
print(a, b, c)
def func2(*args, **kwargs):
print(args) # tuple
print(kwargs) # dict, keywords
func(*args, **kwargs)
func2(1, 2, 3)
# Output
(1, 2, 3)
{}
1 2 3
func2(a=1, b=2, c=3)
# Output
()
{'a': 1, 'b': 2, 'c': 3}
1 2 3
可以看到*args
传入函数的是一个元组,**kwargs
传入函数的是一个字典。
注意:使用**kwargs
传入字典参数时,要保证字典的key跟函数参数名是一致的。
接下来再看一个示例,我们有两个模型,分别需要不同的参数,同时我们有一个模型调用函数,这个模型调用函数可以根据我们指定的模型,调用相应的模型,如果不用可变参数,就需要这样写:
def model_a(a):
pass
def model_b(a, b):
pass
def model_caller(model, a, b):
if model == model_a:
model_a(a)
elif model == model_b:
model_b(a, b)
else:
pass
这样写如果我还有其他模型,例如’model_c’,那么就需要再增加一个判断条件了,这样就很麻烦。
如果使用可变参数,那么代码可以写成这样:
def model_a(a, *args, **kwargs):
pass
def model_b(a, b, *args, **kwargs):
pass
def model_caller(model, a, b):
model(a, b)
这样我们就可以把参数如何使用交给具体的模型自己控制了。
解包(Unpacking)
对于列表类型的数据,就可以通过*
解包传入函数:
args = [1, 2, 3]
func2(*args)
# Output
(1, 2, 3)
{}
1 2 3
对于字典类型的数据,就可以通过**
解包传入函数:
kwargs = {'a': 1, 'b': 2, 'c': 3}
func2(**kwargs)
# Output
()
{'a': 1, 'b': 2, 'c': 3}
1 2 3
下面这种写法,输出是什么呢?
d = {1: 'a', 2: 'b'}
print(*d)
答案是:
1 2
因为字典的keys是可迭代对象,可以这样操作:
for i in d:
print(i)
# Output
1
2
所以可以理解为*
可以对任何可迭代对象进行解包,甚至生成器也是可以的:
func2(*(i for i in range(3)))
# Output
(0, 1, 2)
{}
0 1 2
注意:这里解包后必须传入函数作为参数,无法单独运行。
从任意长度的可迭代对象中分解元素
Python中的*表达式
可以从可迭代对象中分解出来多个元素。
在计算平均值的时候,有时候我们可能会去掉最高分跟最低分,只获取中间部份元素进行计算:
# 去除最高分和最低分,剩下分数取平均
grades = [89, 90, 90, 91, 92, 99]
first, *middle, last = grades
middle
# Output
[90, 90, 91, 92]
还有一个很常见的场景,就是只需要获取前面几个元素,后面的其他元素我们都不需要用到,那么可以使用常见的表示待丢弃值的变量名,例如_
和ign(ignored)
。
record = ('xiaoming', 50, 155, 66)
name, age, *_ = record
name
跟age
分别存储了前两个元素,后面的所有元素值都被丢弃不使用了。
以上就是本文介绍的3个常用的星号*
用法了,当然还有很多其他的妙用,在本文中无法一一体现。