python中的函数

一、递归

        递归就是函数调用自身的过程,先递推,然后回归得到目标结果。

        注意:使用递归必须要有终止条件,否则函数会不停地调用本身无法停止。

接下来会具体举一些栗子证明递归在函数使用过程中可以简化代码:

1.递归可以有循环的效果

def fun(x):  #x为整数
    if x>0:
        print(x,end=" ")
        x-=1
        fun(x)
n = int(input())
fun(n)

2.迭代和递归实现阶乘

        1).用迭代实现阶乘

def t(n):
    if n == 1 or n == 0:
        return 1
    else:
        return n*t(n-1)
n = int(input())
print(t(n))

3149e88bf0a34ed28caab09ba2e8a2db.png

        2).用递归实现阶乘

        原理:当n=1或n=0时阶乘为1;n大于1时阶乘就等于n*factRecur(n-1)

def factRecur(n):
    if n == 1 or n == 0:
        return 1
    else:
        return n*factRecur(n-1)
n = int(input())
print(factRecur(n))

930a38c84a51459492292d5ca117f9fb.png

d626aff4000d4012aa3e1a3b0e9d8588.png4464cd7ba8764345ab8388dcd367022b.png

                                                                完成回归过程

0d283205e67e400cac6fd793843758d3.png

3).经典递归问题:汉诺塔

        第一步:n=1时,直接把盘子从A移到C。而n>1时需要用递归解决先把盘子分为两部分,第一部分为1个,第二部分为n-1个看为一个整体。

        第二步:n>1时,递推过程:第一次调用函数先把n-1个盘子当为整体从A借助C移动到B,输出打印本次过程剩下最后一个盘子从A移动到C。

        第三步:n>1时,回归过程:第二次调用函数先把n-1个盘子当为整体从B借助A移动到C。

在第二步和第三步执行时不用在代码里写出移动每个盘子的过程,用递归这种方法简化过程,由电脑自己推出过程。如果不用递归解决汉诺塔问题那么就需要更加复杂的程序(比如用栈堆的方式解决问题)。

count = 0
def hanoi(n,a,b,c):
    global count
    if n > 0:
        hanoi(n-1,a,c,b)               
        print("Moving %s to %s"%(a,c))   
        hanoi(n-1,b,a,c)               
        count += 1
n = int(input("请输入一个正整数:"))
hanoi(n,'A','B','C')
print(count)
#递归特点:1.不断调用自己的函数  2.结束函数(一定条件下)

        很多时候用递归解决问题,会简化程序,但是递归有递推的过程会占用大量空间。

二、lambda函数c4008116ba424914b271a7bb5528b54c.png

        lambda 参数1,参数2,...,参数n : 表达式 (lambda函数相当于是一个化简后的函数)

1). lambda也可以当作函数调用

s = lambda x:x**2
n = int(input())
re = s(n)
print(re)

fa678eacf5bb4d2e91669d9bfe155c8c.png

2).lambda和sort()或sorted()应用

        lambda函数的作用是让整个l重新排列的依据是按每个人的成绩从低到高排序

l = [{"name": "Alice", "grade": 80},{"name": "Charlie", "grade": 70},{"name": "Bob", "grade": 90}]
l.sort(key=lambda x:x["grade"])
print(l)

8a95c15223f142c6a813004ec9183b41.png

        lambda函数的作用先把列表里所有元素转化为int类型相互之间可以比较大小,然后是按数字大小从低到高排序

r = ["9","1","4","5","3","0"]
re = sorted(r,key=lambda x:int(x))
print(re)

b8289b81727c4df18b34385fe960bca1.png

三、闭包

        函数中的局部变量(函数内部创建的变量),在函数执行完成后,这个局部变量就会自动销毁。如下:函数执行完后,从外部读取局部变量,这个时候却显示它没有被定义。

闭包特点:

1.嵌套函数的外层具有记忆功能(外层函数中表达式或局部变量)。

2.内层函数作为返回值返回给外层函数。

        但是有一个方法可以延长函数中局部变量的“性命”,就是闭包函数。闭包是一种函数,它是由另一个函数返回的内部函数,并且这个内部函数引用了外部函数的变量,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。这个被内部函数引用的外部函数的变量称为自由变量。

def outer_function(x):
    def inner_function(y):
        return x+y
    return inner_function
c = outer_function(10)
print(c)
print("-------------")
print("result=",c(5))

 代码解释:

outer_function

1.接受一个参数x。

2.定义了 inner_function,这个内部函数接受一个参数y,并将x和y相加。

3.最后返回 inner_function

创建闭包:

       1. 调用 outer_function(10) 时,它会返回 inner_function,同时 inner_function 会记住 x 的值为 10。这个返回的 inner_function 就是一个闭包,因为它记住了 x 的值。

        2.当调用c(5)时,实际上是调用inner_function(5),由于闭包的特性,它会将之前记住的x(即 10)和y(即5)相加,得到 15。

闭包的应用:

1.数据隐藏和封装:保护函数内部数据不被外部访问。

2.函数功能多样化:写一个函数框架实现多种功能。

函数闭包里可以用nonlocal关键字在内部函数修改外部函数的变量。

def outer():
    x = 10
    def inner():
        # 错误写法
        # x += 1
        # 正确写法
        nonlocal x
        x += 1
        return x
    return inner


closure = outer()
print(closure())  

7.总结

1).闭包是由另一个函数返回的内部函数,内部函数引用了外部函数的变量。

2).闭包可以用于数据隐藏、封装、函数工厂等场景。

3).在内部函数中修改外部函数的变量时,需要使用nonlocal关键字。

        闭包可以用于保持状态,以及代码简洁性是 Python 函数式编程的重要概念,通过合理使用闭包,可以写出简洁、优雅和功能强大的代码,同时能够更好地管理函数的状态和变量。

四、装饰器

        函数也可以作为参数传给另外一个函数,这时候就要用到装饰器了。装饰器可以用于记录函数执行的时间、在不改变原函数的情况下,为函数增加额外的功能、可以在类中使用...

装饰器特点:多个装饰器在一起时,执行程序是从下到上。

没有用装饰器:

import time
def time_(fun):
    start_time = time.time()
    fun()
    end_time = time.time()
    print(f"一共耗费时间执行fun(x,y)函数时间为:{end_time-start_time}秒")
def fun():
    time.sleep(1)
    print("Hello World!")
time_(fun)

使用装饰器:

import time
def time_(fun):
    def t():
        start_time = time.time()
        fun()
        end_time = time.time()
        print(f"一共耗费时间执行fun(x,y)函数时间为:{end_time-start_time}秒")
    return t

@time_
def myfun():
    time.sleep(1)
    print("Hello World!")

myfun()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值