Python 函数式编程

- 在python中函数是一等对象

- 一等对象一般都会具有如下特点:

  1. 对象是在运行时创建
  2. 能赋值给变量或作为数据结构中的元素
  3. 能作为参数传递
  4. 能作为返回值返回

- 高阶函数

高阶函数至少要符合以下两个特点中的一个:

  1. 接收一个或多个函数作为参数
  2. 将函数作为返回值返回 

当我们使用函数作为参数时,实际上是将指定的代码传递进了目标函数。

l=[1,2,3,4,5,6,7,9,8]
定义一个函数将列表中的偶数保存到一个新的列表中返回。
相当于对列表进行筛选
def fn2(i):
    if i % 2 == 0:
        return True
    return False

def fn(func,lst):
    '''
    将指定列表中的偶数保存到一个新的列表中返回
    :return: 新列表
    '''
    new_list=[]
    for n in lst:
     #   if n%2==0:
        if func(n):
            new_list.append(n)
    return new_list
print(fn(fn2,l)) 传的是函数对象,不要加括号,加括号表示调用函数。

结果:[2, 4, 6, 8]

-filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中

参数:

1,函数,根据该函数来过滤序列(可迭代结构)

2,需要过滤的序列(可迭代结构)

返回值:

过滤后的新序列(可迭代结构)

print(list(filter(fn2,l)))
或者
r=filter(fn2,l)
print(list(r))
结果:[2, 4, 6, 8]

-匿名函数

lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式。(语法糖)

lambda 参数列表:返回值

匿名函数一般都是作为参数使用,其他地方一般不会使用。

l=[1,2,3,4,5,6,7,9,8]

def fn5(a,b):
    return a+b

fn6=lambda a,b : a+b

#调用函数
print((lambda a,b : a+b) (10,20))
或
print(fn6(50,50))

r=filter(lambda  i : i%3==0,l)
print(list(r))

结果:
30
100
[3, 6, 9]

-map()函数可以对可迭代对象中的所有元素做指定操作,然后将其添加到一个新的对象中返回。

l=[1,2,3,4,5,6,7,8]
r=map(lambda i : i**2,l)
print(list(r))
结果:
[1, 4, 9, 16, 25, 36, 49, 64]

-sort()该方法用来对列表中的元素进行排序。默认是直接比较列表中元素的大小。str和int比较不了,会报错。而字符串之间比较,其实就是比较unicode编码。

l=['aaa','ddd','c','z','nnn']
l.sort()
print(l)
结果:
['aaa', 'c', 'ddd', 'nnn', 'z']

在sort()可以接收一个关键字参数,key

key需要一个函数作为参数,当设置了函数作为参数,每次都会以列表中的一个元素作为参数来调用函数,并且使用函数返回值来比较元素大小。

l=['aaa','ddd','c','z','nnn']
l.sort(key=len)
print(l)
通过长度来排序
['c', 'z', 'aaa', 'ddd', 'nnn']

l=[2,5,'1','3',10,'1']又有数字又有字符串
l.sort(key=int)把每一个元素转为int再进行比较
print(l)

['1', '1', 2, '3', 5, 10]

-sorted()是一个函数,和sort()用法基本一致。但是sorted()可以对任意的序列进行排序,并且使用sorted()排序不会影响原来的对象,而是返回一个新对象。

l=[2,5,'1',3,'6','4']
print('排序前:',l)
print(sorted(l,key=int))
print('排序后:',l)
结果:
排序前: [2, 5, '1', 3, '6', '4']
['1', 2, 3, '4', 5, '6']
排序后: [2, 5, '1', 3, '6', '4']

也可以对字符串
l='12387645'
print('排序前:',l)
print(sorted(l,key=int))
print('排序后:',l)
结果:
排序前: 12387645
['1', '2', '3', '4', '5', '6', '7', '8']
排序后: 12387645

第二种高阶函数,将函数作为返回值返回。

-闭包

def fn():
    a=10
    def inner():
        print('我是fn2',a)
    return inner  将内部函数inner作为返回值返回

r=fn()
print(r)
r()
#print(a) 报错,a只有inner能看到和使用
结果:
<function fn.<locals>.inner at 0x00000245557F4040>
我是fn2 10

这种高阶函数也称为闭包,通过闭包可以创建一些只有当前函数能访问的变量。

可以将一些私有的数据藏到闭包中。

求多个数的平均值
1.固定几个数
nums=[10,5,88,30]#固定几个数
#sum()内置函数求一个列表中所有元素的和
print(sum(nums)/len(nums))

2.数值不固定,通过闭包。
def make_aver():
    mylist=[]   #用来保存数值,全局变量很容易改变,所以需要变为私有数据
    def aver(n):
        mylist.append(n)#向列表添加值
        return sum(mylist)/len(mylist)
    return aver
averager =make_aver()
print(averager(10))
print(averager(20))
print(averager(30))
结果:
10.0
15.0
20.0

形成闭包的要点:

1.函数嵌套

2.将内部函数作为返回值返回

3.内部函数必须要使用到外部函数的变量

-装饰器

 

 -装饰器的使用

上面的方式已经可以在不修改源代码的情况下对函数进行扩展了。

但是这种方式要求我们每扩展一个函数就要手动创建一个新的函数,实在麻烦。

为了解决这个问题,我们创建一个函数,让这个函数自动的帮我们生产函数。

def add(a,b):
    r=a+b
    return r

def begin(old):
    '''
    用来对其他函数进行扩展
    :param old: 要扩展的函数对象
    :return:
    '''
    #创建一个新函数
    def newfn(*args,**kwards):#*用来接收所有位置参数,**用来接收所有关键字参数。有就接收没有也行。
        print('开始执行~~')
        result=old(*args,**kwards)#调用被扩展的函数
        print('执行结束~~')
        return result
    #newfn()需要适用于有参数的函数,也要适用于无参数的函数。
    return newfn
#f=begin(add)
#r=f(123,456)
#print(r)
向begin()这种函数我称之为装饰器
通过装饰器,可以在不修改原函数的情况下对函数进行扩展,一般在开发中,经常通过装饰器来扩展函数功能
在定义函数时,可以通过@装饰器,来使用知道的装饰器来装饰当前函数,
可以为一个函数指定多个装饰器,这样函数将会按照由内向外的顺序被装饰。

@begin#加上装饰器
def hello():
    print('大家好')

hello()


结果:
开始执行~~
大家好
执行结束~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会是小张吧!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值