python_day4(2019-05-18)

函数续集

参数

函数的参数除了上次的位置参数,关键字参数,默认参数外,还有可变长参数和混合参数。

  • 可变长参数
    将形参变量前用一个 * 修饰(如 * param),则会将传入的任意数量参数作为一个元组param传入;若用两个 ** 修饰(如**kwargs),则会将显式传入的参数作为一组键值对放入字典kwargs内传入
# 变长参数 将元素放入一个元组内  要放在最后
def self_print(name,*a):
    print('name是:',name)
    print('a是:',a)
    print(type('a的类型是',type(a)))
self_print(1,2,3,4)

# 变长参数 将元素放入一个字典内
def d_self_print(**kwargs):
    print(kwargs)
    print(type(kwargs))
d_self_print(last_name = 'zhang',first_name = 'san')
# 运行结果
name是: 1
a是: (2, 3, 4)
a的类型是 <class 'tuple'>
{'last_name': 'zhang', 'first_name': 'san'}
kwargs的类型是: <class 'dict'>
  • 混合参数
    当位置参数和可变长参数混合使用时,要严格注意放置顺序。参数顺序:位置参数->元组->字典
def mix(name,*t,**kw):
    print('name是:', name,'类型是:',type(name))
    print('t是:', t,'类型是:',type(t))
    print('kw是:', kw,'类型是:',type(kw))

mix('zhangsan',1,2,3,gender = 'female',weight = 600)
# 运行结果
name是: zhangsan 类型是: <class 'str'>
t是: (1, 2, 3) 类型是: <class 'tuple'>
kw是: {'gender': 'female', 'weight': 600} 类型是: <class 'dict'>
参数传递方式
  • 值传递(两个人是双胞胎)
    参数传递的本质就是赋值操作,其中值传递就是赋值时传的是数值,python中的基本数据类型都是值传递 int,bool,string,none。
a = 5   
b = a   
b = 10  
print(a)

# 运行结果
5

通过这个例子我们可以看到,值传递只是把自己的值复制了一份,并赋给另一个变量,而自身并没有改变。故a仍然是5。

  • 引用传递(可以看作起别名)
    而引用传递在赋值时,则是把自己的内存地址直接交给另一个变量,一荣俱荣,一损俱损。经过这种方式赋值的,表面是两个变量,实际上是同一个东西。
l1 = [1,2,3,4,
l2 = l1       
l2[0] = 0     
print(l1)     
[1, 2, 3, 4, 5]
[0, 2, 3, 4, 5]

我们可以看到,把l1赋给l2,然后改变l2的值,l1也随之改变。

  • 注意
    若是引用类型,则需要注意,是否传入的参数在函数体执行过程中对其本体做出了修改。
关于符号 *
  • 融合(在形参位置时)
    这个作用我们刚刚已经看到了,一个 * 会将诸多变量融合为元组,而 ** 则会将其转化为字典。
  • 拆解(其他)
    与上面对应,一个 * 可以拆解元组/列表 ,而 ** 可以拆解字典 。
# * 示例
t = (1,2,3,
print(*t)  

def f(*tt):               
    print(tt)             
f(*[1,2,3,4,5])           
 # ** 示例                        
def ff(**kwargs):         
    print(kwargs)         
ff(**{'a':'name','b':2})  
# 运行结果
1 2 3 4 5
(1, 2, 3, 4, 5)
{'b': 2, 'a': 'name'}
return 返回值

在定义函数时,使用关键字return指明返回值。当有多个返回值时,则需要相应个数的变量依次来获取这些返回值。

def sum_and_avg(*numbers):                 
    total = sum(numbers)                   
    avg_number = total / len(numbers)      
                                           
    return total,avg_number                
sum,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
print('sum是:%f'% sum)                      
print('avg是:%f'% avg)                      
# 运行结果
sum是:55.000000
avg是:5.500000
函数闭包

闭包的本质是函数嵌套函数,外层函数返回内层函数的地址(把内层函数打包)

  • 函数名的本质
    函数名的本质是一个地址,因此可以赋值给另一个变量(函数名)
def fun():                 
    print("hello world!")  
# 函数名的本质是函数的地址             
fun_1= fun                 
fun_1()    

# 运行结果
hello world!                
  • 函数嵌套
    函数嵌套就是在一个函数声明体中,有另一个函数的声明。
  1. 内层函数可以访问外层函数的变量,但不能修改。
  2. 内层函数访问变量时,先从自己内部查找,如果找不到,则会层层向上
  3. python中变量的作用域是以函数为单位的。
  4. global修饰时,说明用的是最外层的全局变量。
  5. nonlocal修饰时,说明使用的的是嵌套层的变量。
def outter():
    a = 10
    def inner():
        print("---------")
        a = 20
        print(a)
        print("hello inner!")
    print(a)
    return inner
outter_1 = outter()
outter_1() 
# 运行结果
10
---------
20
hello inner!
递归函数

递归函数就是在自己的声明内调用自己。

  • 在递归实现时,只需考虑两点:第一明确出口控制(即什么时候递归结束),第二明确递归关系。
  • 递归的优点是简化思考,缺点是消耗高。
  • 附例: 使用递归实现阶乘
def factorial1(n):
    if n == 1:   # 出口
        return 1
    return n * factorial1(n - 1) # 递归关系
print(factorial(5))

# 运行结果
120
高阶函数

高阶函数是这么一种函数,就是这个函数的参数或返回值仍然是一个函数的函数。

def handle(func,*param):  # 第一个参数和返回值是函数func
    return func(*param)

def my_sum(*prama):
    sum = 0
    for v in prama:
        sum += v
    return sum
def my_multiply(*prama):
    mul = 1
    for v in prama:
        mul *= v
    return mul
# 函数的参数是函数
print(handle(my_sum,1,2,3,4,5,6))
print(handle(my_multiply,1,2,3,4,5,6))
# 运行结果
21
720
  • 函数 map(func,iterable)
    该函数会把iterable中的数据一次传递给func函数处理,最后把处理的结果返回。
def power(x):
    return x*x
result = map(power,[1,2,3,4,5]) #结果是一个生成器
print(list(result))
# 运行结果
[1, 4, 9, 16, 25]

试着用lambda表达式实现。

  • 函数 reduce(func,iterable)
    该函数为累计操作,其中func函数必须接纳两个参数,reduce把func的运行结果作为一个参数,然后从iterable中再去一个数据当做另一个参数。
from functools import reduce
li =[1,2,3,4,5]
result = reduce(lambda x,y:x*y,li)
print(result)
# 运行结果
120
  • 函数 fliter(func,iterable)
    该函数的作用是 过滤,根据函数func过滤iterable,True保留,否则删除。
li = [1,2,4,5,6,9,10,15]
result = list(filter(lambda x:x %2 == 1,li))
print(result)
# 运行结果
[1, 5, 9, 15]
  • 函数 sort(iterable,key = None,reverse =Fales)
    对数据进行排序,key用来指定排序规则,值是一个函数,reverse用来指定排序的顺序: 升序或者降序。
li = [1,-10,2,-4,12]
# rs = li.sort()#就地排序
rs = sorted(li,key= abs)
print(rs)
print(li)
# 运行结果
[1, 2, -4, -10, 12]
[1, -10, 2, -4, 12]
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容