第二模块第19章 面向过程与函数式
egon老师知乎文章:
https://zhuanlan.zhihu.com/p/109125933
一 二分法
# 算法: 高效解决问题的办法 # 算法之二分法 # 列表中的数字由小到大排列, 请找出某个值, 如何做更高效 lst = [1, 2, 3, 5, 7, 12, 14, 15, 17, 19, 20, 22, 25, 30] # 方案一: def func1(find_num, lst): for i in lst: if i == find_num: print('find number {}'.format(i)) func1(3, lst) # 方案二: def func(find_num, lst): if find_num in lst: mid_index = len(lst) // 2 mid_value = lst[mid_index] if find_num > mid_value: lst = lst[mid_index + 1:] print(lst) elif find_num < mid_value: lst = lst[0:mid_index] print(lst) else: print('find number {}'. format(find_num)) return func(find_num, lst) else: print('not find number') func(50, lst)
# 注意, 如果列表中的元素是无序的, 则无法直接使用二分法, 需要先进行排序, 即lst.sort()
二 编程思想/范式
1. 面向过程的变成思想
过程即流程.
基于该思想编写程序就好比在设计一条流水线.
优点: 复杂的问题流程化, 进而简单化
缺点: 扩展性非常差
面向过程的编程思想应用场景解析:
1. 不是所有软件都需要频繁更迭, 比如编写脚本
2. 即便是一个软件需要频繁更迭, 也并不代表这个软件的所有部分都需要一起更迭
三 函数式
函数式编程并非用函数编程这么简单,而是将计算机的运算视为数学意义上的运算,比起面向过程,函数式更加注重的是执行结果而非执行的过程,代表语言有:Haskell、Erlang。而python并不是一门函数式编程语言,但是仍为我们提供了很多函数式编程好的特性,如lambda,map,reduce,filter
3.1 匿名函数与lambda
# 1. def用于定义有名函数 # func = 函数的内存地址 def func(x, y): return x+y print(func) # 结果: <function func at 0x000001F5220BC268>, 函数名字为func # 2. lambda用于定义匿名函数 # 没有函数名, 有参数, 参数规则同有名函数, 通常使用位置参数即可. print(lambda x, y: x+y) # 结果: <function <lambda> at 0x000001F5226A1AE8>, 无函数名, 统一名称为lambda ''' 注意: 1. 参数不要加括号 2. :不能省略 3. 函数体代码中不要加return, 默认带有return 4. 函数体中通常写个表达式 ''' # 3. 调用匿名函数 # 方式一: 定义的内存地址没有捆绑任何名字, 在定义后会被回收, 所以要定以后立马使用. # 匿名函数用于临时调用一次的场景: 更多地是将匿名函数与其他函数配合使用 res = (lambda x, y: x+y)(1, 2) # 将函数用括号括起来, 直接调用, python会将(1, 2)误认为是修饰y的 print(res) # 结果: 3 # 方式二: 这样做不如定义有名函数, 不要这么做. func = lambda x, y: x+y print(func) # 结果: <function <lambda> at 0x0000026375071AE8> res = func(1, 2) print(res) # 结果: 3 # 应用案例: salaries = { 'saly': 3000, 'tom': 4000, 'jason': 7000, 'jack': 6000 } # 需求1: 找出薪资最高的人 res = max(salaries, key = lambda k: salaries[k]) print(res) ''' 说明: max()会迭代salaries, 并将迭代出来的值作为参数传给后面的key对应的函数, 然后比较key对应的值. 分解如下: def func(k): return salaries[k] res = max(salaries, key=func) max()会迭代salaries, 并将迭代出的值作为参数传给后面的func, 然后比较key对应的值. min()的用法同max(). 在使用sorted()处理列表时, 可以直接比较, 但是在比较字典中的值时, 则需要用到与max()相同的方法. '''
salaries = {
'saly': 3000,
'tom': 4000,
'jason': 7000,
'jack': 6000
}
res = sorted(salaries, key=lambda k:salaries[k], reverse=True)
print(res) # 结果: ['jason', 'jack', 'tom', 'saly']
3.2 map filter reduce (了解)
# map(了解) lst1 = ['alex', 'lxx', 'egon'] res1 = map(lambda name:name+'_dsb', lst1) print(res1) # 结果: <map object at 0x00000248C7A03C88>, 得到一个生成器 # map()第一个参数传函数, 第二个参数传可迭代对象. # map迭代列表, 然后将迭代得到的元素传给前面的函数. # 以上需求使用列表生成式也可以实现. # filter(了解) lst2 = ['alex', 'lxx_dsb', 'egon'] res2 = (name for name in lst2 if name.endswith('dsb')) print(res2) res3 = filter(lambda name: name.endswith('dsb'), lst2) # 将判断结果为True的留下来, 得到的是一个迭代器 print(res3) # reduce(了解): 合并操作 # 在python2中是内置函数, 但是到了python3中就不是了. from functools import reduce res4 = reduce(lambda x,y:x+y, [11,22,33], 0) print(res4) # 最后的0是起始值 # 第一次运算: 将0和11传给lambda, 然后将得到的结果和22再传给lambda. # 如果没有设定初始值, 则会将迭代对象中的一个值作为初始值.