Lec 6 High-order function map || reduce || filter || sorted
可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
集合数据类型如 list / dict / str 等是Iterable但不是Iterator,可以通过iter()函数获得Iterator对象。
map()函数接收两个参数,一个为函数,一个为Interable,map()将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
1、把函数f(x)=x2,作用在list [0,1,2,3,4,5,6,7,8,9]上:
def f(x): return x*x >>> r = map(f,range(10)) >>> list(r) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
2、list内所有数字转为字符串:
>>> list(map(str,[0,1,2,3,4,5,6,7,8,9])) ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
3、字符串转换为单个数字序列:
>>> def char2num(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] 字典由key取value 输入s为char
>>> list(map(char2num,'13579'))
[1, 3, 5, 7, 9]
reduce表示如下,f每次必须接收两个参数:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
1、把序列[1,3,5,7,9]变成整数13579:
>>> from functools import reduce >>> def fn(x,y): return x*10+y >>> reduce(fn,[1,3,5,7,9]) 13579
2、str2int ('13579'通过map变为[1,3,5,7,9]通过reduce变为13579)
>>> from functools import reduce >>> def fn(x,y): return x*10+y >>> def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] >>> reduce(fn,map(char2num,'13579')) 13579
int('123')= 123的实现:
>>> int('123') 123 >>> from functools import reduce >>> def fn(x, y): return x * 10 + y >>> def char2num(s): return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] >>> def str2int(s): return reduce(fn, map(char2num, s)) >>> str2int('123') 123
练习:
1.利用map()函数,将不规范的英文名字变成首字母大写、其余小写的规范格式 : 输入L1=['adam','LISA','barT'] 输出L2=['Adam','Lisa','Bart']
>>> def normalize(name): return name.capitalize() >>> L1 = ['adam','LISA','barT'] >>> L2 = list(map(normalize,L1)) >>> print(L2) ['Adam', 'Lisa', 'Bart']
2.编写prod()函数,可以接受一个list并用reduce()求积:
>>> from functools import reduce >>> def prod(L): def f1(x,y): return x*y return reduce(f1,L) >>> L = [3,5,7,9] >>> print('3*5*7*9=',prod(L)) 3*5*7*9= 945
3.利用map和reduce编写一个str2float函数,把字符串'123.456'变成浮点数123.456 :
(1) 去小数点
>>> s = '123.456' s.find('.') = 3 小数点对应的索引 >>> s[:s.find('.')] s[:3] = '123'(索引012) '123' >>> s[(s.find('.')+1):] '456' >>> s[:s.find('.')]+s[(s.find('.')+1):] '123456'
(2) str2float
from functools import reduce >>> def str2float(s): def f1(i): return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[i] 字典由key找value --字符串变对应数字 def f2(x,y): return x*10 + y i = s.find('.') t = s[:i]+s[(i+1):] t仍为str return reduce(f2,map(f1,t))/10**(len(t)-i) map 字符串变序列 reduce 序列变整数 >>> str2float('123.456') 123.456
filter()接收一个函数和一个序列,把函数依次作用于序列的每一个元素,根据返回值是true还是false决定保留还是舍弃该元素。
留奇数删偶数:
>>> def is_odd(n):
return n % 2 == 1
>>> list(filter(is_odd,[1,2,3,4,5]))
[1, 3, 5]
sorted()是高阶函数,利用sorted排序的关键在于实现映射函数。
1.对list进行排序:
>>> sorted([20,30,-10,5,-15])
[-15, -10, 5, 20, 30]
2.sorted是高阶函数,可以利用key函数实现自定义排序,例如按绝对值大小进行排序:
>>> sorted([10,-19,5,40],key = abs)
[5, 10, -19, 40]
3.list元素为字符串:(默认按照首字母ASCII大小进行排序)
>>> sorted(['lr','Blake','Paul','Jamal']) ['Blake', 'Jamal', 'Paul', 'lr']
忽略大小写:
>>> sorted(['lr','Blake','Paul','Jamal'],key = str.lower) ['Blake', 'Jamal', 'lr', 'Paul']
反向排序:
>>> sorted(['lr','Blake','Paul','Jamal'],key = str.lower,reverse = True) ['Paul', 'lr', 'Jamal', 'Blake']
(注意True首字母大写)
练习:用一组tuple表示学生成绩,分别按名字和成绩排序: ⚠⚠⚠ tuple () list [] dict{}
>>> L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] L为list,包含4个tuple >>> def by_name(t): return t[0] 返回tuple第一个元素 >>> def by_score(t): return t[1] >>> L1 = sorted(L,key = by_name) >>> print(L1) [('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)] >>> L2 = sorted(L,key = by_score,reverse = True) 默认排序从小到大 >>> print(L2) [('Adam', 92), ('Lisa', 88), ('Bob', 75), ('Bart', 66)]
浙公网安备 33010602011771号