函数式编程

函数式编程

高阶函数

函数不止可以接受变量,还可以接受函数。其实函数名本身就是一种变量,也是可以指向的。而接受函数作为参数的函数就称之为高阶函数。

map和reduce

map函数就是一个高阶函数,它接受两个参数,其中一个是函数,另一个是iterable。 iterable中的每一个元素都会被接受的这个函数作用一次,并最终返回。注意map函数的结果并不是一个list或者tuple,dic,set.而是一个iterator。
列如,我们现在要得到一个11+22+33+……+100100,用map函数怎么做呢?

def f(x):
    return(x*x)
 r=map(f,range(1,101)
 print(sum(list(r)))


可以看到,range(1,101)中的100个元素都被函数f(x)作用了一次,并储存在iterator中。需要用list函数把它转化成list后才能求和,当然,也可以用next函数取出其中包含的值。
reduce也是可以接受两个参数,一个是函数,一个是iterable.但是,它于map不同的有两点,第一点是接受的函数,reduce中的函数可以接受两个参数,并且其中一个参数是上一次运算的结果。第二点就是最后的结果,map函数最后的结果是一个iterator,需要用list或者next才能取出其中的值,而reduce的结果并不是iterator。还有一个要注意的就是调用reduce函数前需要在代码上加一行,from functools import reduce.从functools中调用reduce函数。
下面举一个例子。将一个list中的元素转化成int,比如说把[1,2,3,6,2,4]转化成123624.

from functools import reduce
def char_num(*n):
    def num(x,y):
        return(10*x+y)
     m=reduce(num,n)

课后题
1.利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam’, ‘LISA’, ‘barT’],输出:[‘Adam’, ‘Lisa’, ‘Bart’]

def normalize(name)
    return(name[0].upper(),name[1:].lower())
 print(map(normalize,['adam', 'LISA', 'barT']))



2.利用map和reduce编写一个str2float函数,把字符串’123.456’转换成浮点数123.456

    from functools import reduce
def str2float(s):
    a={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
    def D(x):
        return(a[x])
    def f(x,y):
        return(10*x+y)
    s=s.split('.')
    m_1=reduce(f,map(D,s[0]))
    m_2=reduce(f,map(D,s[1]))/(10**len(s[1]))
               
    return(m_1+m_2)
print('str2float(\'123.456\') =', str2float('123.456'))
if abs(str2float('123.456') - 123.456) < 0.00001:
    print('测试成功!')
else:
    print('测试失败!')

学习了reduce和map函数的用法,注意调用reduce函数时要在开头加一段from functools import reduce
reduce函数使用时里面的第一个变量是一个函数,函数可以接受两个值,开始时函数作用于
开始的两个值,然后计算的结果作为其中一个值,再接受第三个值,函数再作用于这两个值
再一直循环下去
s.split(’.’)的作用是将一个interable以“."为分界线分成两部分
小数部分的处理是先将数字组装成整数,再除以10**len(小数部分)

filter

filter也是一个高阶函数,它也是接受两个参数,一个函数,一个iterable。它参数中的函数return回的是true或者False。如果返回的是True,那么,filter就会返回原先进去的那个自变量。如果返回的是False,那么filtër就不会返回。而且要注意,filter返回的结果是一个iterator。
列如:

def f_2n(n):
    return(n%2==0)
    #这个函数的作用是判断一个数是否是二的倍数
 m=list(filter(f_2n,range(1,101))#生成一个list其中的元素是1到100之间的偶数。

课后题
回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数

def is_palindrome(n):
     return(str(n[:]==str(n[::-1])
     #反向切片,并把两个列表转化成str进行比较,因为我只需判断它反向过来后于原来是否相等。
sorted

sorted也是一个高阶函数,但是它接受的函数参数是固定的,是一个映射函数,虽然我们可以通过改变key来改变映射的对象,但是,它排序的本领是不会发生改变的。
课后题
假设我们用一组tuple表示学生名字和成绩:
L = [(‘Bob’, 75), (‘Adam’, 92), (‘Bart’, 66), (‘Lisa’, 88)]

请用sorted()对上述列表分别按名字排序:

def by_name(t):
    return(t[0])
 L_1=sorted( [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)],key=by_name)
 print(L_1)


这个题目的关键是如何将元组中的元素拿出来,注意到sorted函数是将L迭代一遍,其中的每一个元素都会被单独拿出来,这样的话就可以先让sorted把L[0]拿出来,再把key看做拿出来的那个元组的第一个元素,所以函数by_name的作用就是拿出元组的中第一个元素

返回函数 return

return不仅可以返回函数计算的结果,也可以返回一个函数。比如说,

def f(*x):
    def g():
        sum=0
        for a in x:
           sum=sum+a
        return(sum)
    return(g)
 L=f(1,2,3)
 #在powershell里面输入L,结果是<function f.<locals>.g at 0x00592DF8>,当调用L()时,返回的结果是6


从上面这个例子中就可以看出return还可以返回一个函数的形式,要注意只是一个形式,并不会计算结果,只有当你再次调用的时候,它才会把数值代入进去计算。下面这个例子可以说明这个问题。

def f(*x):
 k=[]
 for a in x:
  def g():
   return(a*a)
  k.append(g)
 return(k)
 L=f(1,2,3)
 L1,L2,L3=L()
 #在这个例子里面,L实际上是[x*x,x*x,x*x]而不是[1,4,9].a是一个外部的变量,内部函数在计算的时候无法调用外部变量,内部函数保存的是一个函数的形式,不是函数计算的结果。所以最终L1,L2,L3的结果都是9

匿名函数 lambda

用于简化函数形式。例如

def f(x):
    return x*x
 L=list(map(f,range(10)))
#也可以写成
L=list(map(lambda x:x*x,range(10)))

课后作业
用匿名函数改造下列代码

def is_odd(n):
    return n%2==1
 L=list(filter(is_odd,range(1,20)))
L=list(filter(lambda n:n%2==1,range(1,20)))

就写到这吧,博客还是随缘写吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值