1. 高阶函数
1.1 map/reduce
1.1.1map()
map()接收2个参数,一个函数参数,一个是Iterable,map 将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
示例:
def f(x):
return x*x
r=map(f,[1,2,3,4,5,6,7,8,9])
print(r)
运行结果:
map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
1.1.2reduce()
reduce():把一个函数作用在一个序列[x1,x2,x3,...]上,必须接收2个参数,reduce 把结果继续和序列的下一个元素做累积计算:reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)。
序列[1,2,3,4,5,6,7,8,9]求和:
def f(x,y):
return x+y
r=reduce(f,[1,2,3,4,5,6,7,8,9])
print(r)
运行结果:
把序列[1,2,3,4,5,6,7,8,9]变换成整数123456789:
def f(x,y):
return x*10+y
r=reduce(f,[1,2,3,4,5,6,7,8,9])
print(r)
运行结果:
用map 和reduce 函数,将str 转int
from functools import reduce
DIGITS={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
def str2int(s):
def fn(x,y):
return x*10+y
def char2num(s):
return DIGITS[s]
return reduce(fn,map(char2num,s))
print(str2int(DIGITS))
运行结果:
练习
练习1:利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']:
from functools import reduce
def normailize1(name):
return name[0].upper()+name[1:].lower()
L1=['admam','LISA','barT']
L2=list(map(normailize1,L1))
print(L2)
练习2:Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:
from functools import reduce
def prod(L):
def fn(x,y):
return x*y
return reduce(fn,L)
print('3*5*7*9=',prod([3,5,7,9]))
if prod([3,5,7,9])==945:
print('test sucessfully')
else:
print('test failed')
练习3:利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:
from functools import reduce
DIGITS={'1':1,'2':2,'3':3,'4':4,'5':5,'6':6}
def str2float(s):
L=s.split('.',1)#利用split 函数将字符串以‘.’为分隔符分成2部分:整数部分,小数部分
L1=L[0]#将L第一个元素整数123赋值给L1
L2=L[1]#将L第2个元素小数部分456赋值给L2
L3=L2[::-1]#通过切片,将456转换成654赋给L3
def fn1(x,y):#处理整数部分
return x*10+y
def fn2(x,y):#处理小数部分,得出4.56,所以reduce 最后还要除以10
return x/10+y
def char2num(s):
return DIGITS[s]
return reduce(fn1,map(char2num,L1))+reduce(fn2,map(char2num,L3))/10
print(str2float('123.456'))
1.2 ##filter()函数:用于过滤序列,接收一个函数和一个序列,把传入的函数依次作用于每个元素,然后根据返回值是True 或False决定保留还是丢弃该元素。
示例
练习:回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数
def is_palindrome(n):
n1 = str(n) #把数字转成字符串
if n1[::]==n1[::-1]:#利用切片实现从左往右 从右往左读 数值一样
return n1#返回左右读数值一样的值
output=filter(is_palindrome,range(1,1000))#利用filter 函数将序列中True 的值筛选出来
print(list(output))
运行结果:
ps:通过独立思考运用切片,实现了功能,好高兴,小白加油哈哈哈哈
1.3 sorted():排序函数
示例:
对list 进行排序:
通过接收key 函数来实现自定义排序,例如按绝对值大小排序:
key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和经过key=abs处理过的list:
key=abs:
[36,5,12,9,21]
练习:假设我们用一组tuple表示学生名字和成绩:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
请用sorted()对上述列表分别按名字和分数排序:
L=[('Bob',75),('Adam',92),('Bart',66),('Lisa',88)]
def by_name(t):#根据名字排序
return t[0] #t 是元组的一个元素,即('Bob',75),其本身也是一个元组,t[0]='Bob',t[1]=75
def by_scote(t):#根据分数从高到低排序
return t[1]
L2=sorted(L,key=by_name)
L3=sorted(L,key=by_scote)
print(L2)
print(L3)