面向过程编程思想与匿名函数及其应用
发布日期:2021-05-04 19:07:24 浏览次数:17 分类:技术文章

本文共 4912 字,大约阅读时间需要 16 分钟。

面向过程编程思想与匿名函数及其应用

文章目录

一、面向过程

面向过程的编程思想

核心是过程二字:过程级流程,指的是解决问题先后先后顺序的步骤:先干啥,在干啥,接着干啥?

所以基于该思想编写程序就好比在设计一条流水线。

补充:无论哪种的编程范式设计出的程序, 最终的执行结果都是过程式的. 计算机底层的硬件的工作方式也是过程式的

优点:

降低程序程序的复杂度,将复杂的问题流程化,进而简单化

缺点:

程序的可拓展性极差,举例: 流水线的每道关卡都不可少, 不然影响整个流水线的运行.

面向过程的编程思想应用场景

前言

面向过程的编程思想一般用于功能一旦实现, 就很少需要改变的场景. 如果你要处理的任务是复杂的, 且现需要不断迭代更新和维护的, 那么面向过程的思想就不适用了.因此我们可以总结出以下两点:

  1. 不是所有的软件都需要频繁更迭: 编写脚本
  2. 即使一个软件需要频繁更迭, 也并代表这个软件所有的组成部分需要一起更迭: 登录注册的功能逻辑, djongo框架

二、编程范式

  • 编程范式指的是编程的套路
  • 主要的套路有三种:命令式编程, 函数式编程, 逻辑式编程
  • 常见的面向对象就是命令式编程, 常见的面向过程就是逻辑式编程

三、函数式

什么是函数式?

  • 函数式编程中的函数指的并不是编程语言中的函数(或方法)
  • 它指的是数学意义上的函数,将计算机的运算视为数学意义上的运算,即映射关系(如:y = f(x)),就是 y 和 x 的对应关系

函数式与逻辑式

  • 比起逻辑式,函数式更加注重的是执行结果并非执行的过程
  • 面向过程就是逻辑式
  • 函数式代表语言:Hashell, Erlang

补充:python提供的函数式编程特性

  • Python并不是一门函数式的编程语言,但却提供了很多函数式编程的特性
  • 比如 : lambda, max, min, map, reduce, filter

四、匿名函数(lambda)

什么是匿名函数?

  • 没有名字的函数

应用场景:

  • 临时用一次,通常用于与其他函数配合使用

匿名函数的强调点

  • 匿名函数的本质目的就是要没有名字,若给匿名函数赋值给一个名字事物没有意义的
  • 匿名函数的参数规则、作用域关系与有名函数是一样的
  • 匿名函数的函数体通常应该是一个表达式,该表达式必须要有一个返回值

匿名函数与有名函数对比

  • 有名函数

    # 有名函数,循环使用,保存了名字,通过名字就可以重复引用函数def foo(x,y):    return x**yfoo(2,3)
  • 匿名函数

    #没有函数名,随时随地定义f = lambda x,y:x ** yprint(f(2,4))  # 16# 一般配合应用 : max, min, sorted, map, reduce, filter

匿名函数的基本语法格式

lambda 参数1, 参数2, ..., 参数n: expression

匿名函数的调用方式

方式一:直接加括号就行

res = (lambda x, y: x + y)(7,8)print(res)  # 15

方式二:给函数指定名字

f = lambda x,y:x ** yprint(f(2,4))  # 16# 匿名函数的本质就是没有名字,这里指定名字是没有意义的(匿名函数只用于临时调用一次)# 匿名函数一般用来与其他函数配合使用,以下来展开介绍

五、匿名函数的应用

求最大值与最小值

1.max( ) : 最大值

  • 接收两个参数 : ([可迭代对象],[函数])
  • 注意:第二个参数函数,必须指定关键字形式:key=匿名函数

2.min( ) : 最小值

  • 接收两个参数 : ([可迭代对象],[函数])
  • 注意:第二个参数函数,必须指定关键字形式:key=匿名函数

补充说明:

如果不指定参数: 使用默认方式迭代比较.( 如果迭代的对象是字典, 那么默认迭代方式的是字典的key, 由key作为本次函数的比较依据。)

指定参数: max与min会把迭代完毕以后的结果作为参数传给函数, 如果迭代的对象是字典,那么就会把字典迭代之后的结果。也就是字典的key当做参数。传给lambda函数赋值给定义的参数。然后以返回值作为比较依据

示例:

# 需求: 获取最大薪资或者最小薪资的那个人salaries = {
'siry': 3000, 'tom': 7000, 'lili': 10000, 'jack': 2000}# 函数max会迭代字典salaries, 迭代字典默认取出的key会当作参数传给指定的匿名函数.# 比较依据: 将函数的返回值 salaries[k] 返回, 作为比较依据# 返回结果: 将比较完毕以后的的参数k当作返回值res = max(salaries, key=lambda k: salaries[k])print(res) # lilires = min(salaries, key=lambda k: salaries[k])print(res) # jack

3.sorted( ) : 排序

**注意:只能用于同种类型的数据排序,除了整型和字符串类型。**如果是字符串排序,是以每个字符之间对应的ASCII码进行比较. 如果是列表与列表之间的排序, 是以每个元素作为比较

  • 接收三个参数 : ([可迭代对象],[函数],[排列顺序])

    • 注意:第二个参数函数,必须指定关键字形式:key=匿名函数
    • 第三个参数是排序顺序(默认从小到大reverse=False). 指定从大到小: reverse=True
  • 如果传入的可迭代对象是字典,默认是按照字典的key来进行排序的

    • sorted 函数会迭代可迭代对象中的每个元素, 把迭代后得到的值依次传给匿名函数
    • 如果是字典,那么迭代以后传给字典的就是 key, 最终,以匿名函数的返回值作为比较依据
    • 比如传入的是字典, 默认迭代的就是字典的 key, 那么返回的只就是字典的 key, 虽然你是用 value来进行比较的
  • reverse参数 : **“False”**代表从小到大, **“True”**代表的是从大到小

    #以每个人的薪资来做比较salaries = {
    'siry': 3000, 'tom': 7000, 'lili': 10000, 'jack': 2000}# 默认是按照字典的key进行排序的.res = sorted(salaries)print(res) # ['jack', 'lili', 'siry', 'tom'] -- > 字符串比较按照ASCII码比较: 'j'(106) < 'l'(108) < 's'(115) < 't'(116)# 需求: 按照薪资从小到大排序(默认升序 reverse=False)res = sorted(salaries, key=lambda k: salaries[k])# res = sorted(salaries, key=lambda k: salaries[k], reverse=False)print(res) # ['jack', 'siry', 'tom', 'lili']# 需求: 按照薪资从大到小排序(reverse=True)res = sorted(salaries, key=lambda k: salaries[k], reverse=True)print(res) # ['jack', 'siry', 'tom', 'lili']

运行原理

sorted函数会迭代可迭代对象中的每个元素, 把迭代后得到的值依次传给匿名函数, 如果是字典,那么迭代以后传给字典的就是key。最终,以匿名函数的返回值作为比较依据.排序完毕以后会返回默认迭代可迭代对象的方式。比如: 字典默认迭代的就是key。那么他就会以key作为你的返回值,虽然你比较的依据是字典的value。它的key是基于你value的排序结果排序的key。

map( ) : 映射

  • 接收两个参数 : ([函数],[可迭代对象])
  • 运行原理: map 函数遍历可迭代对象中的每个元素, 把遍历得到的值当做参数传给匿名函数, 以返回值的处理结果当做返回值返回
  • map得到的结果是迭代器对象

示例:

# 需求: 将array的每个元素做平方处理array = [1, 2, 3, 4, 5]res = map(lambda item: item ** 2, array)print(res)  # map得到的结果是迭代器对象. 返回结果: print(list(res))  # [1, 4, 9, 16, 25]# map的替代方案: 使用生成器表达式res = (item ** 2 for item in array)print(res)  # 得到的是一个生成器
at 0x0000022EA48343C0>print(list(res)) # [1, 4, 9, 16, 25]

reduce( ) : 合并

  • 接收三个参数 : ([函数],[可迭代对象],[初始值])
  • **reduce **在python2中是内置函数, 在python3中被集成到模块 functools 中, 需要导入使用
  • 运行原理 : 以初始值作为第一个参数传给 x , 然后迭代传入的可迭代对象, 拿到的值 y 与 x 相加重新赋值给 x , 再次迭代取值, 周而复始, 直到迭代器被迭代完

示例:

# 需求: 对array进行合并求和运算from functools import reducearray = [1, 4, 9, 16, 25]res = reduce(lambda x, y: x + y, array, 0)print(res)  # 55# reduce的替代方案: sumprint(sum(array))  # 55# reduce的替代方案: 使用生成器表达式 + sumsalaries = {
'siry': 3000, 'tom': 7000, 'lili': 10000, 'jack': 2000}res = sum(value for value in salaries.values())print(res) # 22000# 验证(重点理解): 保留x的状态, 将每次y的值与x进行操作, 直至结束li = [1, '2', '3', '4']res = reduce(lambda x, y: x + y if isinstance(y, int) else x + int(y), li)print(res) # 10# 注意: x在初始阶段只被赋值一次, 并保留x的状态, 将每次y的值与x进行操作, 直至结束.# (((10 - 1) - 2) - 3) = 4res = reduce(lambda x, y: x - y, [1, 2, 3], 10)print(res)# ((1 - 2) - 3) = -4 res = reduce(lambda x, y: x - y, [1, 2, 3])print(res)

filten( ) : 过滤

  • 接收两个参数 : ([函数],[可迭代对象])
  • 遍历可迭代对象, 过滤出结果为真的元素, 如果是字典, 最终返回的结果是字典的 key
  • filten 返回的结果是迭代器

示例

# 需求: 对array进行过滤取出大于3小于16的数array = [1, 4, 9, 16, 25]res = filter(lambda item: 16 > item > 3 , array)print(res)  # 
print(list(res)) # [4, 9]# filter的替代方案: 使用生成器表达式res = ()
上一篇:python之内置函数
下一篇:python之三元表达式、生成式、生成器表达式

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年03月26日 06时24分11秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章