
19 python基础--函数式编程
发布日期:2021-05-14 12:22:33
浏览次数:20
分类:精选文章
本文共 6869 字,大约阅读时间需要 22 分钟。
文章目录
1. 函数式编程(FunctionalProgramming)
- 基于lambda演算的一种编程方式
- 程序中只有函数
- 函数可以作为参数,同样可以作为返回值
- 纯函数式编程语言: LISP, Haskell
- Python函数式编程只是借鉴函数式编程的一些特点,可以理解成一半函数式一半Python
2. lambda匿名函数
-
函数: 最大程度复用代码
- 存在问题: 如果函数很小,很短,则会造成啰嗦
- 如果函数被调用次数少,则会造成浪费
- 对于阅读者来说,造成阅读流程的被迫中断
-
lambda表达式(匿名函数):
- 一个表达式,函数体相对简单
- 不是一个代码块,仅仅是一个表达式
- 可以有参数,有多个参数也可以,用逗号隔开
# lambda表达式的用法 1. 以lambda开头 # 2. 紧跟一定的参数(如果有的话) # 3. 参数后用冒号和表达式主题隔开 # 4. 只是一个表达式,所以,没有returnnum = lambda x,y,z: x * 100 + y * 10 + zs = num(1,2,3)print(s)>123
3. 高阶函数
- 把函数作为参数使用的函数,叫高阶函数
##定义函数需要扩大100倍def funA(n): return n * 100##定义函数需要扩大300倍def funB(n, f): # 假定函数是把n扩大100被 return f(n) * 3print( funB(9, funA) )>2700
- 高阶函数-map
- 原意就是映射,即把集合或者列表的元素,每一个元素都按照一定规则进行操作,生成一个新的列表或者集合
- map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
- 语法:map(func, *iterables) --> map object
def f(x): return x * xl = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])for i in l: print(i,end=' ')>1 4 9 16 25 36 49 64 81
- 高阶函数-reduce
- 原意是归并,缩减,把一个可迭代对象最后归并成一个结果
- 对于作为参数的函数要求: 必须由两个参数,必须由返回结果
- reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
- python3中使用reduce需要导入functools包
from functools import reducedef add(m,n): return m + nl = reduce(add,[1,2,3,4,5,6])print(l)>21
- 高阶函数-filter 函数
- 过滤函数: 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
- 跟map相比较:
- 相同:都对列表的每一个元素逐一进行操作
- 不同:
- map会生成一个跟原来数据想对应的新队列
- filter不一定,只要符合条件的才会进入新的数据集合
- filter函数怎么写:
- 利用给定函数进行判断
- 返回值一定是个布尔值
- 调用格式: filter(f, data), f是过滤函数, data是数据
# 对于一个列表,对其进行过滤,偶数组成一个新列表# 需要定义过滤函数要求有输入,返回布尔值def isEven(a): return a % 2 == 0l = [3,4,56,3,2,3,4556,67,4,4,3,23455,43]rst = filter(isEven, l)# 返回的filter内容是一个可迭代对象print(type(rst))print(rst)print([i for i in rst])>[4, 56, 2, 4556, 4, 4]
- 高阶函数-排序
- 把一个序列按照给定算法进行排序
- key: 在排序钱对每一个元素进行key函数运算,可以理解成按照key函数定义的逻辑进行排序
- 语法:sorted(iterable, /, *, key=None, reverse=False)
a = [-43,23,45,6,-23,2,-4345]b = sorted(a,key= abs,reverse=True)print(b)>[-4345, 45, -43, 23, -23, 6, 2]
3. 返回函数
- 函数可以返回具体的值
- 也可以返回一个函数作为结果
# 函数作为返回值返回, 被返回的函数在函数体内定义def myFun1(): def myFun2(): print('In myFun2') return 2 return myFun2a = myFun1()print(type(a))print(a)a()>.myFun2 at 0x01386390> In myFun2--------------------------------------------------------------def myFun3(*args): def myFun4(): sum = 0 for i in args: sum += i return sum return myFun4()b = myFun3(1,2,3,4,5,6,7,8,9)print(b)>4950
- 闭包(closure)
- 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结果,叫闭包
# 闭包常见坑def count(): # 定义列表,列表里存放的是定义的函数 fs = [] for i in range(1,4): # 定义了一个函数f # f是一个闭包结构 def f(): return i*i fs.append(f) return fsf1,f2,f3 = count()print(f1())print(f2())print(f3())>9 9 9
- 出现的问题:
- 造成上述状况的原因是,返回函数引用了变量i, i并非立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都返回的是 3*3
- 此问题描述成:返回闭包时,返回函数不能引用任何循环变量
- 解决方案: 再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不再改变
# 修改上述函数def count2(): def f(j): def g(): return j*j return g fs = [] for i in range(1,4): fs.append(f(i)) return fsf1,f2,f3 = count2()print(f1())print(f2())print(f3())>1 4 9
4. 装饰器
- 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
- 装饰器的使用: 使用@语法, 即在每次要扩展到函数定义前使用@+函数名
- 好处:一点定义,则可以装饰任意函数,且把装饰器的功能直接添加到定义函数的功能上
def hello(): print("Hello world")# 调用hello()# 复制给函数f,并掉用f = hellof()## f 和hello是一个函数print(id(hello))print(id(f))print(hello.__name__)print(f.__name__)>Hello world Hello world 10160216 10160216 hello hello---------------------------------------------------------------def hello(f): def word(*args, **kwargs): print("Hello everyone,Good morning!") return f(*args, **kwargs) return word@hellodef weekday(): print('Today is Wednesday')weekday()@hellodef weather(): print('Today in fine!')weather()>Hello everyone,Good morning! Today is Wednesday>Hello everyone,Good morning! Today in fine!
- 装饰器手动执行示例
##手动执行def hello(f): def word(*args, **kwargs): print("Hello everyone,Good morning!") return f(*args, **kwargs) return worddef weekday(): print('Today is Wednesday')a = hello(weekday)a()>Hello everyone,Good morning! Today is Wednesday
5. 偏函数
- 参数固定的函数,相当于一个由特定参数的函数体
- functools.partial的作用是,把一个函数某些函数固定,返回一个新函数,方便调用
import functoolsint16 = functools.partial(int,base = 16)print(int(234324))print(int16('234324'))>234324>2310948
6. 高阶函数补充
- zip
- 把两个可迭代内容生成一个可迭代的tuple元素类型组成的内容
z1 = [1,2,3,4,5,6]z2 = [11,22,33,44,55,66]z = zip(z1,z2)print(type(z))print(z)z0 = [i for i in z]print(z0)>[(1, 11), (2, 22), (3, 33), (4, 44), (5, 55), (6, 66)]
- enumerate
- 跟zip功能比较像
- 对可迭代对象里的每一元素,配上一个索引,然后索引和内容构成tuple类型
l1 = [11,22,33,44,55]em = enumerate(l1,start=200)l2 = [i for i in em]print(l2)>[(200, 11), (201, 22), (202, 33), (203, 44), (204, 55)]
- collections模块-----namedtuple
- tuple类型,是一个可命名的tuple
import collectionsa = collections.namedtuple('b',['x','y'])c = a(1,2)print(c.x)print(c[0])d = c.x + c.yprint(d)>1 1 3
- collections模块-----deque
- 比较方便的解决了频繁删除插入带来的效率问题
from collections import dequeq = deque(['a', 'b', 'c'])print(q)q.append("d")print(q)q.appendleft('x')print(q)>deque(['a', 'b', 'c']) deque(['a', 'b', 'c', 'd']) deque(['x', 'a', 'b', 'c', 'd'])
- collections模块-----defaultdict
- 当直接读取dict不存在的属性时,直接返回默认值
from collections import defaultdictfunc = lambda :'该键值对不存在,返回默认值替代"KeyError"'a = defaultdict(func)a['one'] = 1a['two'] = 2print(a['one'])print(a['three'])>1 该键值对不存在,返回默认值替代"KeyError"
- collections模块-----Counter
- 统计字符串个数
from collections import Countera = Counter('weqweqfsdvfsdgrdthdgbhdtsdfs')print(a)>Counter({ 'd': 6, 's': 4, 'f': 3, 'w': 2, 'e': 2, 'q': 2, 'g': 2, 't': 2, 'h': 2, 'v': 1, 'r': 1, 'b': 1})
7. 递归函数
定义:函数Func(Type a,…)直接或间接调用函数本身,则该函数称为递归函数.
def fun(n): if n == 1 or n == 2: # 递归临界点,不再调用自身函数的条件 return 1 else: return fun(n-1) + fun(n-2)l = []for i in range(1, 10): l.append(fun(i))print(l)>[1, 1, 2, 3, 5, 8, 13, 21, 34]
递归的弊端:递归函数用很少的代码完成了庞大的功能,但大量的重复计算导致时间与空间的消耗。同时递归深度存在一定限制。
# 方式一: 缓存优化def cache_decorator(func): cache_dict = { } def decorator(arg): try: return cache_dict[arg] except KeyError: return cache_dict.setdefault(arg, func(arg)) return decorator@cache_decoratordef fun(n): if n == 1 or n == 2: return 1 else: return fun(n-1) + fun(n-2)l = []for i in range(1, 30): l.append(fun(i))print(l)
# 方式二: 缓存优化from functools import lru_cache@lru_cachedef fun(n): if n == 1 or n == 2: return 1 else: return fun(n-1) + fun(n-2)l = []for i in range(1, 30): l.append(fun(i))print(l)
8. 纯函数
纯函数:一个函数的返回结果只依赖其参数,并且执行过程中没有副作用
函数的副作用:函数完成既定任务的同时,访问了外部数据,尤其是对外部数据进行了写操作,改变了系统环境。 纯函数的3个原则:1、 变量只在作用域内获取,作为参数传入;2、不会产生副作用;3、相同的输入保证相同的输出
def func(a ,b): return a + b
9. 内置函数
官方文档: https://docs.python.org/zh-cn/3/library/functions.html
# filterl = [1, 33, 45, 34, 77]def func(n): return n < 35r = filter(func, l)print(list(r))>[1, 33, 34]
# filterl = [1, 33, 45, 34, 77]def func(n): return n*2r = map(func, l)print(list(r))>[1, 33, 34]
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月13日 19时13分40秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
springboot2.1.1开启druid数据库连接池并开启监控
2021-05-14
《朝花夕拾》金句摘抄(五)
2021-05-14
《朝花夕拾》金句摘抄(六)
2021-05-14
《金色梦乡》金句摘抄(六)
2021-05-14
Boostrap技能点整理之【网格系统】
2021-05-14
新闻发布项目——业务逻辑层(UserService)
2021-05-14
hibernate正向生成数据库表以及配置——hibernate.cfg.xml
2021-05-14
javaWeb服务详解(含源代码,测试通过,注释) ——Emp的Dao层
2021-05-14
java实现人脸识别源码【含测试效果图】——Dao层(IUserDao)
2021-05-14
使用ueditor实现多图片上传案例——前台数据层(Index.jsp)
2021-05-14
ssm(Spring+Spring mvc+mybatis)——saveDept.jsp
2021-05-14
JavaScript操作BOM对象
2021-05-14
layui二级联动
2021-05-14
解决Chrome播放视频闪屏黑屏无法播放
2021-05-14