高阶函数-递归
admin
2023-07-09 11:04:38
0

1.高阶函数

1.1高阶函数定义

变量可以指向函数,函数的参数能接受变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称为高阶函数。
只要满足以下任意一个条件,即是高阶函数
1.接收一个或多个函数作为输入
2.return返回另外一个函数

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def add(x, y, func):
    return func(x) + func(y)
res = add(3, -6, abs)
print(res)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
9

Process finished with exit code 0

2.递归

2.1递归定义

在函数内部,可以调用其它函数。如果一个函数在内部调用自身,这个函数就是递归函数。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def calc(n):
    print(n)
    if int(n/2) == 0:
        return n
    return calc(int(n/2))
calc(4)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
4
2
1

Process finished with exit code 0

2.2递归的执行过程

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def calc(n):
    print(n)
    if int(n/2) > 0:
        calc(int(n/2))
    print(n)
calc(4)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
4
2
1
1
2
4

Process finished with exit code 0

高阶函数-递归

2.3递归特性

1.必须有一个明确的结束条件
2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用时通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以递归调用的次数过多,会导致栈溢出)

    #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def recursion(n):
    print(n)
    recursion(n + 1)

recursion(1)
运行
...
996
997
998
Process finished with exit code 1
"到998程序就自动停止了,是因为递归的最大深度是有限制的,防止栈溢出"

2.4二分法查找

    #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

data = [1, 3, 5, 7, 8, 10, 30, 34, 35]

def binary_search(source_data, search_data):
    print(source_data)
    if len(source_data) > 1:
        mid_data_index = int(len(source_data)/2)
        if source_data[mid_data_index] == search_data:
            print("excellent,you have found it!")
        elif source_data[mid_data_index] > search_data:
            source_data = source_data[0:mid_data_index]
            binary_search(source_data, search_data)
        elif source_data[mid_data_index] < search_data:
            source_data = source_data[mid_data_index + 1:]
            binary_search(source_data, search_data)
    else:
        if len(source_data) == 0:
            print("source data is null now!")
        else:
            if source_data[0] == search_data:
                print("you have found it!")
            else:
                print("there is not this number!")
binary_search(data, 30)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
[1, 3, 5, 7, 8, 10, 30, 34, 35]
[10, 30, 34, 35]
[10, 30]
excellent,you have found it!

Process finished with exit code 0
"找4"
binary_search(data, 4)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
[1, 3, 5, 7, 8, 10, 30, 34, 35]
[1, 3, 5, 7]
[1, 3]
[]
source data is null now!

Process finished with exit code 0

2.5求阶乘

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def multi(n):
    if n == 1:
        return 1
    else:
        return n*multi(n-1)

print(multi(4))

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
24

Process finished with exit code 0

2.6斐波那契

    #!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
# 1 1 2 3 5 8 13
a = 0
b = 1
n = 0
def fibs(a, b):
    global n
    a, b = b, a + b
    print(a)
    if n == 5:
        return
    n += 1
    fibs(a, b)

fibs(a,b)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
1
1
2
3
5
8

Process finished with exit code 0

2.7尾递归

再讲递归特性时,我们说递归效率不高,因为每递归一次,就多了一层栈,递归次数过多就会栈溢出,这也是Python默认会限制递归次数的原因。但有一种方式是可以在递归过程中不产生多层栈,即尾递归。
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用时整个函数体重最后执行的语句且它的返回值不属于表达式的一部分,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译机会利用这个特点自动生成优化的代码。
当编译器检测到一个函数调用时尾递归,就会覆盖当前活动记录,而不是在栈中去创建新的。编译器可以做到这点,因为递归调用时当前活跃期内最后执行的一条语句,于是当这个调用返回时帧栈中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是重新添加一个,这样就节省了栈帧的使用,运行效率变高。

"尾递归的例子"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def calc(n):
    print(n)
    if n > 0:
        return calc(n-1)
calc(8)

那么阶乘的例子是尾递归吗?
不是尾递归,因为每个活跃的返回值都依赖于用n乘以下一个活跃期的返回值,因此每次调用产生的栈帧不得不保存在栈上直到下一个子调用的返回值确定。

python中实际是没有做尾递归的优化,但别的语言有优化的

相关内容

热门资讯

美前副总统:共和党失去了方向,... 2026年是美国的中期选举年,共和党选情不利,可能在年底的选举中遭遇挫败。美国前副总统彭斯5月31日...
南枝原来去过中国?《给阿嬷的情... 《给阿嬷的情书》票房口碑双丰收,目前票房已突破13亿。凤凰卫视最新一期《问答神州》专访了该片导演蓝鸿...
法国海军扣押一艘俄“影子舰队”... 近日,法国海军在大西洋海域扣押了一艘据称从俄罗斯摩尔曼斯克出发的油轮,引发俄方强烈不满。俄新社6月1...
凤凰晚报丨面粉染头模仿黄仁勋,... 今日人物【面粉染头模仿黄仁勋,农村青年走红后称遭“法务”警告】“先赔偿5000元肖像侵权使用费,再删...
亲特朗普极右派候选人领跑哥伦比... 【文/观察者网 熊超然】当地时间5月31日,哥伦比亚总统选举拉开帷幕,首轮投票计票工作已完成逾99%...
2026年度网络举报系列宣传活... 5月28日至29日,以“每一件举报,都是共治的力量——豫你e行 同心护网”为主题的2026年度网络举...
中原首例帝企鹅DNA性别鉴定!... 近日,郑州海昌海洋公园正式对外公布中原首对人工繁育的帝企鹅萌宝的DNA性别鉴定报告。这是中原首个将 ...
我国科学家为细胞信号“导航”开... 新华社济南5月31日电(记者张力元)人体细胞犹如一座精密的通信城市,每天都有大量“指令”穿梭传递,调...
极端大风突袭哈尔滨!过山车停摆... 极目新闻记者 詹钘5月31日,受强对流天气影响,哈尔滨国际会展中心体育场相关设施受到损坏,原计划当晚...
三原电缆取得电缆接头连接用防护... 国家知识产权局信息显示,上海三原电缆附件有限公司取得一项名为“一种电缆接头连接用防护结构”的专利,授...