一、二分法
二分法是是算法的一种,那算法是什么,算法就是高效的解决问题的办法,我们用一个查找数字的需求来了解算法。
需求:有一个按照从小到大顺序排列的数字列表,需要从中找到我们想要的那一个数字,想想我们怎样才能做到更加的高效。
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
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!