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)]

 

posted @ 2016-11-14 17:54  sniperlr  阅读(95)  评论(0)    收藏  举报