函数递归和编程思想

一、函数递归

1、函数递归调用介绍
函数不仅可以嵌套定义,还可以嵌套调用,即在调用一个函数的过程中,函数内部又调用另一个函数,而函数的递归调用指的是在调用一个函数的过程中又直接或间接地调用该函数本身
例如:
在调用f1的过程中,又调用f1,这就是直接调用函数f1本身
def f1():
    print('from f1')
    f1()
f1()
在调用f1的过程中,又调用f2,而在调用f2的过程中又调用f1,这就是间接调用函数f1本身
def f1():
    print('from f1')
    f2()

def f2():
    print('from f2')
    f1()
f1()
两种情况下的递归调用都是一个无限循环的过程,但在python对函数的递归调用的深度做了限制,因而并不会像大家所想的那样进入无限循环,会抛出异常,要避免出现这种情况,就必须让递归调用在满足某个特定条件下终止。
提示:
      1. 可以使用sys.getrecursionlimit()去查看递归深度,默认值为1000,
虽然可以使用sys.setrecursionlimit()去设定该值,但仍受限于主机操作系统栈大小的限制
      2. python不是一门函数式编程语言,无法对递归进行尾递归优化。
2、递归的过程:
回溯与递推
回溯阶段:代码循环体的运算一直到循环结束
递推阶段:回溯结束后,逆推循环体数据运算结果

使用递归,我们只需要分析出要重复执行的代码逻辑,然后提取进入下一次递归调用的条件或者说递归结束的条件即可,代码实现起来简洁清晰

二、编程思想

1、编程范式:
编程范式指的就是编程的套路,打个比方,如果把编程的过程比喻为练习武功,那编程范式指的就是武林中的各种流派,而在编程的世界里常见的流派有:面向过程、函数式、面向对象等
2、面向过程
​ ”面向过程“核心是“过程”二字,“过程”指的是解决问题的步骤,即先干什么再干什么......,基于面向过程开发程序就好比在设计一条流水线,是一种机械式的思维方式,这正好契合计算机的运行原理:任何程序的执行最终都需要转换成cpu的指令流水按过程调度执行,即无论采用什么语言、无论依据何种编程范式设计出的程序,最终的执行都是过程式的。
3、面向过程总结:
优点:将复杂的问题流程化,进而简单化
缺点:程序的可扩展性极差,因为一套流水线或者流程就是用来解决一个问题,就好比生产汽水的流水线无法生产汽车一样,即便是能,也得是大改,而且改一个组件,与其相关的组件可能都需要修改,比如我们修改了cloud_upload的逻辑,那么依赖其结果才能正常执行的data_backup_check也需要修改,这就造成了连锁反应,而且这一问题会随着程序规模的增大而变得越发的糟糕。

def cloud_upload(file): # 加上异常处理,在出现异常的情况下,没有link返回
    try:
        print("\nconnecting cloud storage center...")
        print("cloud storage connected")
        print("upload [%s] to cloud..." %file)
        link='https://www.xxx.com/bak/%s' %os.path.basename(file)
        print('close connection')
        return link
    except Exception:
        print('upload error')
    finally:
        print('close connection.....')

def data_backup_check(link): # 加上对参数link的判断
    if link:
        print("\n下载文件: %s , 验证文件是否无损..." %link)
    else:
        print('\n链接不存在')
4、应用场景
面向过程的程序设计一般用于那些功能一旦实现之后就很少需要改变的场景, 如果你只是写一些简单的脚本,去做一些一次性任务,用面向过程去实现是极好的,但如果你要处理的任务是复杂的,且需要不断迭代和维护, 那还是用面向对象最为方便。
5、函数式:
函数式编程并非用函数编程这么简单,而是将计算机的运算视为数学意义上的运算,比起面向过程,函数式更加注重的是执行结果而非执行的过程,代表语言有:Haskell、Erlang。而python并不是一门函数式编程语言,但是仍为我们提供了很多函数式编程好的特性,如lambda,map,reduce,filter
匿名函数与lambda
​ 对比使用def关键字创建的是有名字的函数,使用lambda关键字创建则是没有名字的函数,即匿名函数,语法如下

lambda 参数1,参数2,...: expression
内置函数max和min
都支持迭代器协议,工作原理都是迭代字典,取得是字典的键,因而比较的是键的最大和最小值
l={'syy':1000,'ylx':100}
max(l)
=====>
ylx
想要的是比较值的最大值与最小值,
max(l,key=lambda k:l[k])
======>
syy
函数map、reduce、filter都支持迭代器协议,用来处理可迭代对象

map自定义处理规则,生成列表
l=[1,2,3,4,5]
q=map(lambda x:x*2,l)
print(q)
q=list(q)
print(q)
=======》
<map object at 0x00000195BE2FE100>
[2, 4, 6, 8, 10]

reduce合并所有迭代对象,利用数字,字符串运算的规则
需要调用模块
from functools import reduce
l=[1,2,3,4,5]
q=reduce(lambda x,y:x*y,l)
q=int(q)
print(q)
========》
120

filter定义条件删选结果为True的数据,放在列表里
l=[1,2,3,4,5]
q=filter(lambda x:x>3,l)
q=list(q)
print(q)
=========》
[4,5]
posted @ 2020-12-10 16:43  叶灵溪  阅读(146)  评论(0编辑  收藏  举报
aplayer
##============================ /* 看板娘 */ =======================