首页 > 其他 > 详细

函数式编程的介绍

时间:2020-04-20 19:47:27      阅读:65      评论:0      收藏:0      [点我收藏+]

一.为什么不会写程序呢?

答:类比于学英语,如果每说一句话就要想单词怎么说,语法怎么用,就写不出来英语文章。

解决方法:将单词、语法当作自己本能的反应。

所以,学python的时候,应该把这些基本的元素反复使用,重复。

二.代码的风格——编程的三个方法论

(1)面向过程

  找到解决问题的入口,将一个大问题分解成一个个小问题,然后通过代码,逐步解决。(按照一个固定的流程解决问题)

(2)函数式编程

简介

  函数式=编程语言定义的函数+数学意义上的函数。即用编程语言实现数学函数。

  python不是严谨的函数式编程的语言,纯函数式编程的语言有hashell,clean,erlang等

def foo(n):
    print(n)
def bar(name):
    print("afasf")
    return "caonima"      #返回值可以是任何东西,可以是数字,字符串,元组,也可是函数名,这样返回的就是这个函数对应的地址。
                #也可以是函数名+(),这样就是的到函数的返回值 foo(bar(‘ads‘)) #必须给函数的括号里传入一个值,可以是变量名,也可以是字符串之类的

#输出结果 afasf caonima

  

新的概念:高阶函数

高阶函数(满足下列两个条件的函数)

a.函数接受的参数是一个函数名

b.函数的返回值是一个函数

高阶函数的用途,下几节课在讲

新的概念:尾调用 优化

定义:在函数的最后一步,调用另外一个函数(注意,最后一步,不一定等于函数的最后一行代码

优化过程,在最后一步就直接调用下一个,之前的东西不用保存在栈中了,节省了空间。

    如果函数的调用不是最后一步,那么后几步的代码仍然需要保存,占用了空间

 

def foo(n):
    return n
def bar(n):
    return foo(n)+1      #这样就不是尾调用,因为相当于调用了foo(n),再加1,这个加1的过程始终没有执行,等函数运行完了再运算,占用了空间
a=bar(4)
print(a)

 

  

 

以上的内容不用太深层次地掌握,接下来的内容才是重中之重!!!

1.map函数

例:将[1,2,10,5,3,7]每个值都变成他的平方,存放在列表中

#第一种方法,for循环的方式
num_1=[1,2,10,5,3,7]
num=[]
for i in num_1:
    num.append(i*i)
print(num)
#输出结果为[1, 4, 100, 25, 9, 49]

  

但是,有好多好多列表让你这么操作你可咋整??

没关系,哥教你一种新方法-_-!

#第一种方法,for循环的方式
num_1=[1,2,10,5,3,7]
def map_test(array):
    ret=[]
    for i in array:
        ret.append(i**2)
    return  ret
ret=map_test(num_1)          #这样以后再给你一个列表的话,直接调用这个函数就可以了,不用每次都for循环
print(ret)

说白了,就是将上一种方法的for循环的功能封装再一个函数里面,再求直接调用就ok

  

妈的,又提新需求了,要求让这个列表都加一,都减一,都开平方,我们一次次改就很烦啊,这怎么办呢?

哥教你!

def add(x):
    return x+1
def min(x):
    return  x-1                #我们先自己定义两个功能,一个是return输入的值加1,另一个功能减1
num_1=[1,2,10,5,3,7]
def map_test(add,array):       #注意!!!在定义函数的时候加上函数名!!一定不能带括号,否则就执行了
    ret=[]
    for i in array:
        ret.append(add(i))    #往ret里添加的东西用自己定义的 add函数实现
return ret ret=map_test(add,num_1) print(ret) #输出结果为[2, 3, 11, 6, 4, 8] def map_test2(min,array): #这时候,傻逼又提新需求了,我们把自己定义的另一个函数写在这里就ok了 ro=[] for i in array: ro.append(min(i)) return ro print(map_test2(min,num_1)) #输出结果为[0, 1, 9, 4, 2, 6]

  

当然我们可以温故而知新,想一想之前学过的匿名函数

add=lambda x:x+1
num_1=[1,2,10,5,3,7]
def map_test(add,array):
    ret=[]
    for i in array:
        ret.append(add(i))
    return  ret
ret=map_test(lambda x:x+1,num_1)      #把add函数写成匿名函数的形式
print(ret)
#输出结果为[2, 3, 11, 6, 4, 8],结果是一样的!

  

终极简约的形式

num_1=[1,2,10,5,3,7]
def map_test(func,array):      #上面只需要写一个func就行,我们再调用的时候再写匿名函数
    ret=[]
    for i in array:
        ret.append(func(i))
    return  ret
ret=map_test(lambda x:x+1,num_1)        #这里匿名函数的功能是实现+1,还可以写各种各样的呢!
print(ret)
#输出结果为[2, 3, 11, 6, 4, 8]

  

这时,我们引出这节课的主题:map函数

map的用法:    map(操作方式,操作对象)

num_1=[1,2,10,5,3,7]
res=map(lambda x:x+1,num_1)        #神奇不!lambda代表操作方式,后面代表对象!!!注意一点,这样得到的函数输出结果是一个 “可迭代类型”
print(list(res))
#输出结果[2, 3, 11, 6, 4, 8]

也可以将匿名函数换做之前已经写好的函数

num_1=[1,2,10,5,3,7]
res=map(lambda x:x+1,num_1)
print(res) #输出结果<map object at 0x000002AC54B29520>,是一个可迭代器的输出
#对res取一个list,把里面的东西遍历循环,再放在列表里,得到最终的结果
print(list(res))
#输出结果为[2, 3, 11, 6, 4, 8]


小总结:map后面跟两个参数,第一个是处理方式,第二个是处理的对象。把这个处理对象进行for循环遍历,同样得到一个可迭代对象出来,再list出来,就得到一个列表
第二个参数不一定是列表,只要是一个可迭代对象就可以了!
拿字符串转换成大写举例

name=‘yxz‘
res=map(lambda x:x.upper(),name) #逻辑:将name中的每一个元素,这里是字符串的每一个组成元素遍历,依次加入到另一个可迭代对象中
print(list(res)) #将上一行的可迭代对象通过list()操作转换成一个列表进行输出
#输出结果为:[‘Y‘, ‘X‘, ‘Z‘]
 

  

2.filter函数

实现以下的功能:过滤掉列表里以sb开头的名字

第一种方法:for循环

movie_people=["sbalex","sbwu","yxz"]
ret=[]
for i in movie_people:
    if not i.startswith("sb"):
        ret.append(i)
print(ret)

  

第二种方法:写一个函数,大同小异

movie_people=["sbalex","sbwu","yxz"]
def filter_movie(array):
    ret=[]
    for i in array:
        if not i.startswith("sb"):
            ret.append(i)
    return ret               #注意,这里一定要有一个return值
print(filter_movie(movie_people))

  

movie_people=["sbalex","sbwu","yxz"]
def star(n):
    return n.startswith("sb")        #自己先定义了一个函数,判断是否以sb开头
def filter_movie(star,array):       #定义这个函数的时候,先传入一个函数
    ret=[]
    for i in array:
        if not star(i):
            ret.append(i)
    return ret               
print(filter_movie(star,movie_people))
#输出结果为[‘yxz‘]

  

第三种方法:给你好多过滤条件,如以sb结尾或者包含sb怎么办呢?

联系之前的maplambda,写一个终极版本

filter函数的方法:filter(处理方法,可迭代对象)

movie_people=["sbalex","sbwu","yxz"]
res=filter(lambda x:not x.startswith("sb"),movie_people)     #把每一个符合的元素跳出来
print(list(res))      #得到的结果也是一个可迭代对象,我们需要对他取一个list操作

  

小总结:对操作对象中的每一个值做一个for循环,如果满足处理方法,则单独拿出来,放在一个可迭代对象中

    我们为了把得到的可迭代对象输出出来,取一个list操作,再打印即可

 

3.reduce函数

 需要提前导入一个模块

实现以下功能:将列表中所有数值加起来

第一种方法:for循环

num=[1,2,3,4,5,6,100]
sum=0
for i in num:
    sum+=i
print(sum)

  

第二种,写一个函数

num=[1,2,3,4,5,6,100]
def sum_sum(array):
    sum=0
    for i in array:
        sum+=i
    return sum
res=sum_sum(num)
print(res)

  

第三种:之前两种方法把逻辑写死了,我现在想加入一个乘法的功能怎么办?

 

num=[1,2,3,100]
def multi(x,y):
    return x*y                  #先定义一个函数,函数返回值为输入的两个数相乘
def sum_sum(multi,array):
    res=1
    for i in array:
        res=multi(i,res)      #执行这个函数,把列表里的数相乘
    return res
res=sum_sum(multi,num)
print(res)
#输出结果 600

也可以这么写
print(sum_sum(lambda x,y:(x*y),num))     #以匿名函数的方法代替了之前写的乘法函数

  

如果我添一个功能,让一个初始值乘列表所有的数

num=[1,2,3,100]
def multi(x,y):
    return x*y
def sum_sum(multi,array,init=None):      #设定一个初始值,默认为none
    if init is None:
        res=1
        for i in array:
            res=multi(i,res)
        return res
    else:
        res=init                    #若赋予了一个值,则从这开始乘
        for i in array:
            res=multi(i,res)
        return res
res=sum_sum(multi,num,100)
print(res)

  

reduce函数的正式引用(map-reduce)

reduce的作用:将所有的数据压缩在一起,取得一个最终的结果

用法:

step1:导入一个模块  from functools import reduce

step2:  reduce(操作方式,操作对象,初始值(若不写则默认为none))

num=[1,2,3,5,8]
from functools import reduce
res=reduce(lambda x,y:x*y,num)
print(res)
#输出结果为240

num=[1,2,3,5,8]
from functools import reduce
res=reduce(lambda x,y:x*y,num,15)
print(res)
#输出结果为3600

  

 

 

 

 

 

 

函数式编程的介绍

原文:https://www.cnblogs.com/yxzymz/p/12738937.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!