当前位置: 首页 > news >正文

Python基础-----函数式编程含义及特点(及尾递归)

一、定义
函数式就是用编程语言去实现数学函数。这种函数内对象是永恒不变的,要么参数是函数,要么返回值是函数,没for和while循环
所有的循环都由递归去实现,无变量的赋值(即不用变量去保存状态),无赋值即不可改变。
二、特点
1、不可变数据
不可变:不用变量保存状态,不修改变量
a. 非函数式
a = 1
def test():
global a
a += 1
return a
test()
print(a)
>>> 2
b. 函数式
n = 1
def test1(n):
return n+1
print(test1(2))
print(n)
>> 3
1
2、第一类对象
第一类对象:函数即变量
a.函数名可以作为参数传递
def a(n):
print(n)
def b(name):
print('My name is %s'%name)
a(b)
>>> 上述调用为:b不带括号则表示b函数的内存地址,将内存地址作为实参传递给a函数,则a函数打印的为b函数的内存地址
a(b('Liming'))
>>> 'My name is Liming'
None
上述调用为:首先会执行函数b,则先打印出‘My name is Liming’,但是b函数没有定义返回值,则默认为None
则将None作为实参传递给a函数,则a函数打印出None
b.返回值可以是函数名
def a():
print('from a')
def b():
print('from b')
return a
n = b()
n()
>>> 'from a'
'from b'
3、尾调用优化(尾递归)
尾调用:在函数的最后一步调用另外一个函数(最后一行不一定是函数的最后一步)
尾调用优化:尾调用的关键就是在于函数的最后一步调用别的函数,这样的好处是:根据函数即‘变量’的定义,
定义a函数,a内调用b函数,b内调用c函数,在内存中会形成一个调用记录,又称调用帧,用于保存调用位置和内部变
量等信息,即a->b->c直到c返回结果给b,c的调用记录才会消失,b返回给a,b的调用记录消失,a返回结果,a的调用
记录消失,所有的调用记录都是先进后出,形成了一个调用栈。尾调用由于是函数的最后一步操作,所以不需要保留外
层函数的调用记录,因为调用位置、内部变量等信息都不会用到了,只要直接用内层函数的调用记录,取代外层函数的
调用记录就可以了。
def bar(n)
return n
def foo(x):
return bar(x)
print(foo(3))
>>> 3
上述foo(3)就等于bar(3),也就是说foo在最后一步调用了bar,然后foo的调用记录就清楚了,剩下的就是bar
自己的事情了。所以内存里永远只保留一个调用记录。

尾递归:函数调用自身成为递归,如果尾调用自身,就成为尾递归。
尾递归特点:重复相同的事情,每次重复会使问题规模减少。
尾递归举例:
问题:师傅,北京怎么去啊?
解决方法:a去问b,b不知道,b去问c,c去问d,最有由d得出结果,此过程可以发现,问题最有只需要d去
结局即可,a b c都无需保存任何记录,不干事,因为他们啥都不知道。
尾递归优点:递归通常非常耗费内存,因为需要同时保存成千上百个调用记录,很容易发生‘栈溢出’错误。
但对于尾递归来说,由于只存在一个调用记录,所以不会发生‘栈溢出’错误。
def cal(l):
print(l)
if len(l) == 1:
return l[0]
first,second,*args = l
l[0] = first + second
l.pop(1)
return cal(l)
x = cal([i for i in range(10)])
print(x)
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[3, 3, 4, 5, 6, 7, 8, 9]
[6, 4, 5, 6, 7, 8, 9]
[10, 5, 6, 7, 8, 9]
[15, 6, 7, 8, 9]
[21, 7, 8, 9]
[28, 8, 9]
[36, 9]
[45]
45
上例就是用到尾递归,最终求得1~9的和

转载于:https://www.cnblogs.com/Meanwey/p/9741228.html

相关文章:

  • 第一次用.net2.0 LOGIN登陆控件的困惑和解决方法。
  • docker 容器详解
  • 2分分页处理存储过程通用存储过程
  • 洛谷P3379 【模板】最近公共祖先(LCA)(dfs序+倍增)
  • QTP关于验证码的应用解决方法之一
  • [Swift]LeetCode217. 存在重复元素 | Contains Duplicate
  • 网管日志-06.07.18
  • unity 中 Tilemap的使用 笔记
  • 正版和盗版对开发的影响(请注意这个问题)
  • github上更新fork项目
  • 基于DBDataAccess类的具体数据访问类,这些代码大部分都可以自动生成。
  • 通俗易懂系列 | 设计模式(八):建造者模式
  • O血型的性格
  • entity
  • 01-python学习之路
  • python3.6+scrapy+mysql 爬虫实战
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • docker python 配置
  • golang中接口赋值与方法集
  • Invalidate和postInvalidate的区别
  • IP路由与转发
  • JavaScript HTML DOM
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • leetcode-27. Remove Element
  • Linux CTF 逆向入门
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • PhantomJS 安装
  • Ruby 2.x 源代码分析:扩展 概述
  • supervisor 永不挂掉的进程 安装以及使用
  • 高度不固定时垂直居中
  • 蓝海存储开关机注意事项总结
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 新手搭建网站的主要流程
  • 06-01 点餐小程序前台界面搭建
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #微信小程序(布局、渲染层基础知识)
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (C语言)逆序输出字符串
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)负载均衡,回话保持,cookie
  • .bat批处理出现中文乱码的情况
  • .NET MVC 验证码
  • .net mvc部分视图
  • .so文件(linux系统)
  • [ linux ] linux 命令英文全称及解释
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [BUUCTF]-Reverse:reverse3解析
  • [BZOJ 3680]吊打XXX(模拟退火)