(1)函数式编程里,特征之一就是 高阶函数
(2)高阶函数特点:
函数可以用来赋值,调用其他函数(函数名)作为参数,返回函数(函数名)
实际上就是
var=funcA()
def funcA(funcB):
return funcB
(3)一般来说,都是用的函数名func,而不是函数 func()
因为func()往往不返回,或者返回其他obj 只有closure才返回函数名 func
(4)为什么叫高阶函数,不是高级
而是因为调用了函数,函数层级更高
(5)今天这里整体python内置的3个高阶函数
map(func,obj)
reduce(func,obj)
filter(obj,key=xxx,reverse=True)
题目:需要对[1,2,3,4,5,6,7,8,9]每个元素都进行平方
#想对一个list里的元素进行平方运算,直接带入参数像int一样计算却不可以
#如果是list里,应该是数列对应元素相乘
方式1:直接写一个平方函数,然后调用函数时,把list当参数直接带入,这样会报错
>>> def funcA(a):
return a*a
>>> m=[1,2,3,4,5,6,7,8,9]
>>> funcA(m)
Traceback (most recent call last):
File "
funcA(m)
File "
return a*a
TypeError: can't multiply sequence by non-int of type 'list'
方式2:既然不能直接用list相乘,那么可以把list里元素拿出来,先进行int级的运算,然后加回到另外一个list里去。
>>> def funcX():
listA1=[]
for i in [1,2,3,4,5,6,7,8,9]:
listA1.append(i*i)
return listA1
>>> funcX()
[1, 4, 9, 16, 25, 36, 49, 64, 81]
方法3和4 #本着数据和函数分离的思路,改写
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> def squareY(y):
listB=[]
for i in y:
listB.append(i*i)
return listB
>>> squareY(listA)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
# 这是我现在能想到的,数据和函数过程的最大分离程度
#操作函数:square() #方便复用和模块化
#被操作对象处理函数 squareList() #方便复用和模块化
#具体的数据对象listA #方便修改和传入
>>> def squareA(a): #运算函数
return a*a
>>> def squareListA(a): #list处理函数
listB=[]
for i in a:
listB.append(squareA(i))
return listB
>>> listA=[1,2,3,4,5,6,7,8,9] #数据对象
>>> squareListA(listA)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
MAP函数的定义
map()是 Python 内置的高阶函数
语法:map (func,obj-sequence)
过程:它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上
return:得到一个新的 sequence---iterators 并返回。(并不是返回的list,需要再转为list tuple等)
方法5 map方法 #使用map函数--确实快捷
>>> def squareB(b):
return b*b
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> list(map(squareB,listA))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
利用map函数实现格式化list内的string 大小写
>>> listB=["adAM","LILY","tom"]
>>> def format(a):
return a[0].upper()+a[1:].lower()
>>> list(map(format,listB))
['Adam', 'Lily', 'Tom']
参考:https://www.cnblogs.com/superxuezhazha/p/5714970.html
2个参数,另外一个是序列:list tuple都可以
而且不改变老的,生成新序列,所以新的也可以是list tuple 甚至set,dict 都可以
>>> list(map(format,listB))
['Adam', 'Lily', 'Tom']
>>> tupleB=("adAM","LILY","tom")
>>> list(map(format,tupleB))
['Adam', 'Lily', 'Tom']
>>> tuple(map(format,tupleB))
('Adam', 'Lily', 'Tom')
>>> set(map(format,tupleB))
{'Lily', 'Adam', 'Tom'}
>>> dict.fromkeys(map(format,listB))
{'Adam': None, 'Lily': None, 'Tom': None}
题目:计算[1,2,3,4,5,6,7,8,9]的和
reduce函数定义
语法: reduce(func,obj--sequence)
reduce()函数是,把函数依次作用在list的上,并且可能一次不只操作1个元素,并且对这些计算的结果进行加和。
return:一个表达式的运算结果。
环境:需要导入模块 functools
关于redunce(),参考文档 https://www.cnblogs.com/lonkiss/p/understanding-python-reduce-function.html
官方文档介绍
reduce(...)
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
从左到右对一个序列的项累计地应用有两个参数的函数,以此合并序列到一个单一值。
例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 计算的就是((((1+2)+3)+4)+5)。
如果提供了 initial 参数,计算时它将被放在序列的所有项前面,如果序列是空的,它也就是计算的默认结果值了
序列 其实就是python中 tuple list dictionary string 以及其他可迭代物,别的编程语言可能有数组。
reduce 有 三个参数
function | 有两个参数的函数, 必需参数 |
sequence | tuple ,list ,dictionary, string等可迭代物,必需参数 |
initial | 初始值, 可选参数 |
reduce的工作过程是 :在迭代sequence(tuple ,list ,dictionary, string等可迭代物)的过程中,首先把 前两个元素传给 函数参数,函数加工后,然后把得到的结果和第三个元素作为两个参数传给函数参数, 函数加工后得到的结果又和第四个元素作为两个参数传给函数参数,依次类推。 如果传入了 initial 值, 那么首先传的就不是 sequence 的第一个和第二个元素,而是 initial值和 第一个元素。经过这样的累计计算之后合并序列到一个单一返回值
>>> from functools import reduce
>>> def addB(a,b):
return a+b
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> reduce(addB,listA)
45
题目:计算[1,2,3,4,5,6,7,8,9]这些数按10进制往上累积
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> def func10(a,b):
return 10*a+b
>>> reduce(func10,listA)
123456789
# 但是很奇怪,用3个参数就报错?界定了函数只能用2个参数!
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> def funcAA(a,b,c):
return a*10+b*5+c
>>> reduce(funcAA,listA)
Traceback (most recent call last):
File "
reduce(funcAA,listA)
TypeError: funcAA() missing 1 required positional argument: 'c'
>>>
语法 filter(func,obj-sequence)
过程:根据函数对 序列的每个元素进行筛选
return: iterators---sequence 返回的是一个新的,可迭代对象,序列
都是接受2个参数 第1个函数,第2个序列
测试:
odd numbers 奇数
even numbers 偶数
>>> def is_odd(n):
return n%2==1
>>> listA=[1,2,3,4,5,6,7,8,9]
>>> list(filter(is_odd,listA))
[1, 3, 5, 7, 9]
去掉空格
>>> def not_none(s):
return s and s.strip()
>>> strA="aabbasasc asanjk skjhiuujhaha"
>>> list(filter(not_none,strA))
['a', 'a', 'b', 'b', 'a', 's', 'a', 's', 'c', 'a', 's', 'a', 'n', 'j', 'k', 's', 'k', 'j', 'h', 'i', 'u', 'u', 'j', 'h', 'a', 'h', 'a']
#重新变成str很难,本身 str---list(str)----str(list(str)) 本身就会无法转回去
# str.join(iterable-obj) 而且必须是带引号的字符串,不能是int等
>>> "_".join(list(filter(not_none,strA)))
'a_a_b_b_a_s_a_s_c_a_s_a_n_j_k_s_k_j_h_i_u_u_j_h_a_h_a'
>>> "".join(list(filter(not_none,strA)))
'aabbasascasanjkskjhiuujhaha'
语法:Sorted(squence,key=xx,reverse=True)
过程: 对suqence 排序,并且如果有key ,会根据key的要求进行排序
return: squence-obj
比较
list.sort() 方法
sorted() 函数,内置函数 ,而且,不存在sort() 函数!
>>> listA=[1,4,12,4,12423,298]
>>> listA.sort()
>>> listA
[1, 4, 4, 12, 298, 12423]
>>> sort(listA)
Traceback (most recent call last):
File "
sort(listA)
NameError: name 'sort' is not defined
>>> sorted(listA)
[1, 4, 4, 12, 298, 12423]
高阶函数用法
>>> listB=[1,-5,90,-124,75]
>>> sorted(listB,key=abs)
[1, -5, 75, 90, -124]
>>>
参数的用法
默认参数/可选参数 reverse=ture
Key= str.lower #可以在排序时,忽略实际大小写,按小写排序比较。
Key=str.upper
Key=str.swapcase 理论上str的方法都可以传进来?
>>> listB=["ahasHHJ","CjhaskIO","bKKAttyYUING"]
>>> sorted(listB,key=str.lower)
['ahasHHJ', 'bKKAttyYUING', 'CjhaskIO']
>>> sorted(listB)
['CjhaskIO', 'ahasHHJ', 'bKKAttyYUING']
>>>
用作按一个值的蓄力,映射排序
>>> score=[("john",75),("bob",60),("simon",90),("lily",85)]
>>> sorted(score,key=lambda x:x[1])
[('bob', 60), ('john', 75), ('lily', 85), ('simon', 90)]