匿名函数、编程范式、模块

一、二分法

二分法是是算法的一种,那算法是什么,算法就是高效的解决问题的办法,我们用一个查找数字的需求来了解算法。

需求:有一个按照从小到大顺序排列的数字列表,需要从中找到我们想要的那一个数字,想想我们怎样才能做到更加的高效。

nums = [-1, 2, 4, 5, 6, 8, 10, 12, 15, 30, 44]
find_num = 6

# 如果是一个无序的列表我们可以调用列表的sort方法进行从大到小排序
nums1=[-4,3,2,1,10,8,20,43,11,9]
nums.sort()
print(nums1)

方案一:

首先我们可能第一时间想到的是用for循环遍历加判断的方法查找

for num in nums:
    if num == find_num:
        print(f'find {find_num}')
        break

分析:如果列表元素很多,这样整体遍历来查找的效率太低,那我们有没有更加高效的查找办法呢?

方案二:

二分法

(百度一下)

对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。

用二分法查找列表中的数字:

nums=[-3,4,7,10,13,21,43,77,89]

def binary_search(find_num, l):
    print(l)
    if len(l) == 0:
        print('找的值不在列表中')
        return
    mid_index = len(l) // 2
    if find_num > l[mid_index]:
        # 查找列表的右半部分
        l = l[mid_index + 1:]
        binary_search(find_num, l)
    elif find_num < l[mid_index]:
        # 查找列表的左半部分
        l = l[:mid_index]
        binary_search(find_num, l)
    else:
        print(find_num)

binary_search(-3, nums)
#调用函数结果:
[-3, 4, 7, 10, 13, 21, 43, 77, 89]
[-3, 4, 7, 10]
[-3, 4]
[-3]
-3

二、面向过程编程范式

1、面向过程的编程范式(编程思想):

核心是“过程”二字,那什么是过程,过程即流程,指的是 做事的步骤,基于面向过程编写程序就好比在设计一条流水线

步骤:第一步、第二步、第三步、...

优点:把复杂的问题流程话、进而简单化

缺点:因为编写的程序成一条流水线,其中一个地方的修改有可能会影响多个地方或整条流水线,所以扩展性非常的差

2、面向过程的编程思想应用场景解析:

1)、我们需要知道的是并不是所有的软件或者说功能都需要频繁的更迭,比如注册功能、登录功能,在比如编写一个脚本软件,在这种时候我们即可以使用面向过程的编程范式

2)、即便是一个软件需要频繁更迭,也不并不代表这个软件所有的组成部分都需要一起更迭

三、匿名函数

1、 之前我们用def定义的函数都是有名函数,引用计数不为零,如:

def func(x, y):  # func指向的是函数体的内存地址
    return x * y

2、 现在我们需要定义没有名称的函数即匿名函数,我们需要用到lambda关键字,如:

print(lambda x,y:x*y)

3、匿名函数的调用方式

方式一:

res = (lambda x, y: x * y)(1, 2)  # 用括号将匿名函数框起来,在后面加括号传入参数,最后整体赋值给一个变量
print(res)  #2

方式二:

func = lambda x, y: x * y  #将匿名函数赋值给变量
res = func(1, 2)
print(res)

注意:匿名函数用于调用一次的场景:更多的是将匿名函数与其他函数配合一起使用

四、匿名函数的应用

1、man函数

如果我们需要将一个全是数字的列表当中的最大值找出来可以用max函数

res = max([2, 4, 200, 7, 399])  # 对列表中的每个值进行比较得到最大值
print(res)  # 399

如果是一个字典,则比较的是字典的每个key

salaries = {
    'siry': 3000,
    'tom': 7000,
    'lili': 10000,
    'jack': 2000
}

res = max(salaries)
print(res)  #tom

那我们需要找出此字典中value的最大值怎么办

方法一:

定义一个函数用于获得字典key对应的value:

def func(k):
    return salaries[k]

然后将函数func当成参数传给max:

res = max(salaries, key=lambda k: salaries[k])  #比较value,返回值最大的key
print(res)   #lili 

max的第一个参数是一个可迭代对象,第二个参数是函数,当然也可以是一个匿名函数,所以上述方法换成匿名函数的形式:

res =max(salaries,key=lambda k: salaries[k])  #参数换成了匿名函数
print(res)  #lili

2、min函数

min函数原理和max函数相同,只不过得出来的最小值

res = min(salaries, key=lambda k: salaries[k])  #比较value,返回值最小的key
print(res)  #jack

3、sorted排序

3.1

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}
res=sorted(salaries,key=lambda k:salaries[k])
print(res)  #['jack', 'siry', 'tom', 'lili']

3.2 reverse参数改为True

res=sorted(salaries,key=lambda k:salaries[k],reverse=True)
print(res)  #['lili', 'tom', 'siry', 'jack']

4、map函数

需求将l列表中的每个值都加上后缀'nb'

方法一:

l = ['tom', 'jack', 'mack', 'egon']
new_l = (name + '_nb' for name in l)  #获得一个生成器
#用list迭代出生成器中的内容
print(list(new_l))   #['tom_nb', 'jack_nb', 'mack_nb', 'egon_nb']

方法二:

用map函数映射

res=map(lambda name:name+'_nb',l)  #获得一个生成器
#用list迭代出生成器中的内容
print(list(res))  #['tom_nb', 'jack_nb', 'mack_nb', 'egon_nb']

5、filter函数

用于过滤,满足匿名函数条件的值会被添加进新的列表,不满足的就过滤掉

l = ['tom_nb', 'jack', 'mack', 'egon']

res=filter(lambda name:name.endswith('nb'),l)
print(list(res))  #['tom_nb']

6、reduce函数

使用reduce函数前需要先导入模块

from functools import reduce

reduce需要传入三个参数,第一个是函数,第二是可迭代对象,第三个是初始值,不指定初始值,则会将迭代出的第一个和第二个值当作参数 传入函数,计算得到的值和第三次迭代的值传入函数、

res = reduce(lambda x, y: x + y, [1, 2, 3])  #不指定初始值
print(res)  #6

指定初始值

res = reduce(lambda x, y: x + y, [1, 2, 3],2)
print(res)  #8

五、模块

copy

1、什么是模块?

模块就是一系列功能的集合体,分为三大类
1)内置的模块
2)第三方的模块
3)自定义的模块
一个python文件本身就一个模块,文件名m.py,模块名叫m

        ps:模块有四种形式
          1 使用python编写的.py文件

          2 已被编译为共享库或DLL的C或C++扩展

          3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)

          4 使用C编写并链接到python解释器的内置模块

2、为何要用模块

1)内置与第三的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率
2)自定义的模块,可以将程序的各部分功能提取出来放到一模块中为大家共享使用,好处是减少了代码冗余,程序组织结构更加清晰。

3、如何用模块

1、导入模块

首次导入模块会发生的三件事

import foo

1)执行foo.py

2)产生foo.py的名称空间,将foo.py运行工程中产生的名字都丢到foo的名称空间中去

3)在当前执行文件所在的名称空间中得到一个名字foo,该名字指向新创建的模块名称空间,若要引用模块名称空间中的名字,需要加上该前缀,如下

import foo #导入模块foo
a=foo.x #引用模块foo中变量x的值赋值给当前名称空间中的名字a
foo.get() #调用模块foo的get函数
foo.change() #调用模块foo中的change函数
obj=foo.Foo() #使用模块foo的类Foo来实例化,进一步可以执行obj.func()

注意:之后的导入,都是直接引用首次导入产生的foo.py名称空间,不会重复执行代码

import foo
import foo

2、引用

print(foo.x)
print(foo.get)
print(foo.change)

强调1:模块名.名字,是指名道姓地访问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突

x=1111111111111
print(x)
print(foo.x)

强调2:无论是查看还是修改操作的都是模块本身,与调用位置无关

3、可以以逗号为分隔符在一行导入多个模块

#建议如下所示导入多个模块
import time
import foo
import m
# 不建议在一行同时导入多个模块
import time,foo,m

4、导入模块的规范

1)python内置模块
2)第三方模块
3)程序员自定义模块

每种不同得模块之间用空行隔开

import time
import sys

import 第三方1
import 第三方2

import 自定义模块1
import 自定义模块2
import 自定义模块3

5、导入的模块或方法 as更名成简洁的名称,便于调用

import fooooooo as f

from foo import fbbbbbbbbb  as fb

6、模块是第一类对象

import foo

7、自定义模块的命名规范

自定义模块的命名应该采用纯小写+下划线的风格

8、可以在函数内导入模块

def func():
    import foo

原文链接: https://www.cnblogs.com/cainiaoqianxun/p/12577300.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    匿名函数、编程范式、模块

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/376885

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月3日 下午1:16
下一篇 2023年3月3日 下午1:16

相关推荐