高阶函数:参数或返回值为其他函数的函数
filter(function,iterable):将iterable中的元素放到function中去,根据结果判断bool值,如果是True则留下,如果是False则去掉,如果function为None,则对iterable的每个元素进行bool判断;
# 例如
lis1 = [1, 0, -1, 2, 3, 7, True, False]
obj = filter(lambda x: x + 1, lis1)
print(list(obj))
print('--------------------------')
obj1 = filter(None, lis1)
print(list(obj1))
# 终端显示
[1, 0, 2, 3, 7, True, False] # -1+1=0,因此将-1过滤掉
--------------------------
[1, -1, 2, 3, 7, True] # 将原列表中0过滤掉
注意: 返回一个迭代器
map(func,*iterables):将iterable的每个元素拿出来,进行func运算,并以迭代器的形式返回参数,有多少个iterable,则需要func能接收多少个参数,iterable如果长短不一,则以最短的为主(类似于zip);
# 例如
lis1 = [0, 1, 2, 3, 4, 5]
tup1 = (0, 1, 2, 3, 4)
set1 = {0, 1, 2, 3}
res = map(lambda x, y, z: x+y+z, lis1, tup1, set1)
print(list(res))
# 终端显示
[0, 3, 6, 9]
注意: 返回一个迭代器
reduce(function, iterable[, initial]):将iterable的前两个参数拿出来,进行function,并返回一个值,将返回值与iterable的第三个元素进行function,以此类推,如果initial有值,则第一次拿出initial和iterable的第一个元素,如果iterable为空,则需设置initial,否则会报错,如果iterable只有一个值,initial为空,则会返回iterable的第一个元素,initial不能是关键字参数,function需要能接受两个参数;
# 例如
from functools import reduce # Python3中已经不是内置函数,因此需要导入模块
lis1 = [0, 1, 2, 3, 4, 5, 6, 7]
lis2 = []
lis3 = [1]
obj = reduce(lambda x, y: x + y, lis1) #不上传initial
print(obj)
print('--------------------------')
obj1 = reduce(lambda x, y: x + y, lis1, 100) # 上传initial
print(obj1)
print('--------------------------')
obj2 = reduce(lambda x, y: x + y, lis2, 100) # 列表为空
print(obj2)
print('--------------------------')
obj3 = reduce(lambda x, y: x + y, lis3) # 列表只有一个元素,不上传initial
print(obj3)
print('--------------------------')
obj4 = reduce(None, lis3) # function为空,不上传initial,列表只有一个元素
print(obj4)
print('--------------------------')
obj5 = reduce(None, lis2, 0) # function为空,列表为空,initial上传
print(obj5)
# 终端显示
28
--------------------------
128
--------------------------
100
--------------------------
1
--------------------------
1
--------------------------
0
注意: 返回一个结果,不是可迭代对象
递归函数:函数调用自己的变成技巧称为递归
主要思路:将一个大问题分解为无数的小问题,从小问题推出大问题
两个条件:
1、递归边界条件:到递归边界则终止递归
2、递归推理:不断提取重复的子问题,不断向递归边界靠拢
print(sys.getrecursionlimit()) # 获取最高递归次数,默认1000次,超出会报错
sys.setrecursionlimit(x) # 将递归上限设置为x次
注意:
递归的缺点是效率较低,重复计算次数过多
改进方法:将计算出来的东西存储下来,然后在需要的时候调用即可
# 例如
def func(num):
if num == 1: # 最小子问题,num=1的时候,func(1) = 1,
return 1
num1 = num * func(num-1) # 此处调用自己,切记num不能写成func(num),否则会陷入死循环
return num1
print(func(5)) # num1 = 5 * func(4)
# func(4) = 4 * func(3)
# func(3) = 3 * func(2)
# func(2) = 2 * func(1)
# func(1) = 1
#终端显示
120 # 累加也可以用一样的思路解题
第一个人年龄是10,后面每个人年龄比前一个大2岁,求第8个人的年龄
# 例如
def func(num):
if num == 1:
return 10
return func(num-1)+2
print(func(8))
# 终端显示
24
# 例如
def func(string1):
if len(string1) == 1:
return string1[0]
return string1[len(string1)-1]+func(string1[0:len(string1)-1])
string1 = input()
print(func(string1))
# 终端显示
abcd
dcba
输出第n个斐波那契数列
# 例如
def func(n):
if n < 2:
return 1
return func(n-1) + func(n-2)
print(func(5))
# 终端显示
8
注意: 由于重复计算量过大,导致效率低,越靠后的数,计算时间越长,因此可以做改进,将重复性强的计算以字典的形式存储起来,需要的时候直接从字典中取出来,可以大大提高效率,即用空间换时间
# 例如
def func(n):
dict1 = {} # 建立空字典存放数据
if n < 2:
return 1
if n in dict1: # 如果在字典中则直接取数
return dict1[n]
res = func(n-1)+func(n-2) # 否则递归计算
if n not in dict1: # 如果不字典中则放入字典中
dict1[n] = res
return res
print(func(20))
# 终端显示
10946
面向对象编程区别于面向过程编程
程序 = 算法(逻辑) + 数据
面向对象重数据,面向过程重算法(逻辑)
面向对象的特点:高内聚,低耦合(高内聚是指每个版块内部联系紧密,低耦合是指各模块与各模块之间的联系较小)
面向过程的特点:高内聚(高内聚是指面向过程编程重逻辑性,整个编程是一体的,整体内部联系性较强)
面向过程编程比较杂糅,不容易修改,不够灵活