Python 练习-函数式编程-(01)高阶函数

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)

运行结果:

image.png

map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。


image.png

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)

运行结果:

image.png

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

运行结果:

image.png

练习

练习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决定保留还是丢弃该元素。

示例

image.png

练习:回数是指从左向右读和从右向左读都是一样的数,例如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))

运行结果:

image.png

ps:通过独立思考运用切片,实现了功能,好高兴,小白加油哈哈哈哈

1.3 sorted():排序函数

示例:

对list 进行排序:

image.png

通过接收key 函数来实现自定义排序,例如按绝对值大小排序:

image.png

key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。对比原始的list和经过key=abs处理过的list:
key=abs:
[36,5,12,9,21]

image.png

练习:假设我们用一组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)

你可能感兴趣的:(Python 练习-函数式编程-(01)高阶函数)