函数进阶
2019-05-18 本文已影响0人
Vector_Wan
主要包括:
- 星号表达式(starred expression)
- 快速传入多个参数
- 变长度参数的传入
- 多个返回值的情况
一、快速传入多个参数
函数在调用多个参数时,在列表、元组、集合、字典及其他可迭代对象作为实参,并在前面加 *后传入
如 *(1,2,3)
解释器将自动进行解包然后传递给多个单变量参数(参数个数要对应相等)。
我理解 *可迭代对象
就是将可迭代对象与普通对象之间相互转化的运算符。
但是特别注意:表达式不可单独使用!*
我们先来看几个小李子:
t = (1,2,3,4)
print(*t)
t2 = [5,6,7,8]
print(*t2)
1 2 3 4
5 6 7 8
所以我们可以多个参数写进一个元组里,然后把这个元组当做相应函数的参数列表传进去:
def f(a, b, c, d):
print(a, b, c, d, sep = '&')
f(1,2,3,4)
f(*(1,2,3,4))
1&2&3&4
1&2&3&4
传入列表也是可以的:
*会将列表[1,2,3,4]中的数字取出来,分别赋给参数a,b,c,d
def f(a, b, c, d):
print(a, b, c, d, sep = '&')
f(1,2,3,4)
f(*[1,2,3,4])
1&2&3&4
1&2&3&4
下面这个函数可以实现与上面一样的功能:
注意print函数中的 args 前面必须加 * 号
def f(*args):
print(*args, sep='&')
f(1,2,3,4)
f(*(1,2,3))
1&2&3&4
1&2&3
这个用法有些意思,下面详细介绍一下:
二、将任意个数的参数导入到python函数中(变长参数的传入)
出现在函数的参数中的星号表达式 *args
用于将传入的可迭代参数序列解析出来,并存入 args
中。
- *args 会将传入的变长参数放入名为 args 的元组中
- **kwargs 会将传入的变长参数放入名为 kwargs 的字典中
1.使用*args
将传入的变长参数放入名为 args 的元组中
def self_print(*a):
print(a)
print(type(a))
self_print(1,2,3,4,5,6)
(1, 2, 3, 4, 5, 6)
<class 'tuple'>
def self_print(name,*a):
print(a)
print(type(a))
self_print(1,2,3,4,5,6)
(2, 3, 4, 5, 6)
<class 'tuple'>
上面这个用法使用了Python的拆包操作。第一个值赋给 name 剩下的参数存入名字为 a 的元组中。
下面来看一个实际的应用:用numpy创建一个大小与m相同的随机矩阵:
由于矩阵 m 的维度不能确定所以采用变长参数传入
import numpy as np
np.random.randn(*m.shape)
函数randn接收n个可选参数:numpy.random.randn(d0, d1, …, dn)
2.使用**kwargs
将将传入的参数放入名为 kwargs 的字典中
- 字典名为 kwargs
- 字典的键为形参(就这么记吧估计实际上并不是)
- 字典的值为实参
def d_self_print(**kwargs):
print(kwargs)
print(type(kwargs))
d_self_print(last_name = "Wan", first_name = "Vector")
{'last_name': 'Wan', 'first_name': 'Vector'}
<class 'dict'>
3. 混合参数的传入
注意形参的顺序:位置参数->元组->字典
def mix(name, *t, **kw):
print(name)
print(t)
print(kw)
mix("Vector",20,'NEUQ',) # 当参数为空 注意那个逗号!!!
print('*'*20)
mix("Vector",20,'NEUQ',gender = "男")
Vector
(20, 'NEUQ')
{}
********************
Vector
(20, 'NEUQ')
{'gender': '男'}
# 这是一个错误的示范:
def mix( *t, **kw, name = 'qq'):
print(name)
print(t)
print(kw)
File "<ipython-input-12-d64f7f8770cc>", line 2
def mix( *t, **kw, name = 'qq'):
^
SyntaxError: invalid syntax
def mix(name, last_name = 'a', *t, **kw):
print(name)
print(last_name)
print(t)
print(kw)
mix("Vector",20,'NEUQ',) # 当参数为空
Vector
20
('NEUQ',)
{}
三、返回多个返回值
def sum_and_avg (*numbs):
total = sum(numbs)
avg_number = total/ len(numbs)
return total, avg_number
sum_of_num,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
print('总和是:%f'%sum_of_num)
print('平均值为:%f'%avg)
总和是:55.000000
平均值为:5.500000
下面是一些关于星号表达式的补充:
一、用于 unpack 可迭代的变量
1.赋值语句中的 * 用于列表数值取出
a, *b, c = range(5)
print('a:',a,'\nb:' ,b,'\nc:' ,c)
a: 0
b: [1, 2, 3]
c: 4
record = ('Vector', 50, 123.45, (5, 18, 2019))
name, *_1, (*_2, year) = record
print('name:',name,'\n_1:',_1,'\n_2:',_2,'\nyear:',year)
name: Vector
_1: [50, 123.45]
_2: [5, 18]
year: 2019
for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
print(b)
[2, 3]
[5, 6, 7]
- 用于递归(列表求和)
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
items = [1, 10, 7, 4, 5, 9]
print(sum(items))
36
注意:表达式不可单独使用!*
错误用法:
>>> *a = range(5)
>>> a = *range(5)
>>> print(*range(5))
# 正确用法
*a, = range(5)
a = *range(5),
*a,b = range(5)
print(*range(5),)
0 1 2 3 4
这让我想到了单独一个元素的数组应该写成(a,)
a = 1
print(type(a,))
print(type(a))
print(type((a,)))
<class 'int'>
<class 'int'>
<class 'tuple'>