第二模块第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.
# 如果没有设定初始值, 则会将迭代对象中的一个值作为初始值.

 

posted @ 2020-06-28 10:20  自由者妍  阅读(142)  评论(0)    收藏  举报