Python中高级特性函数式编程(lambda表达式、高阶函数、map、reduce、filter、排序、返回函数、闭包closure、装饰器Decrator、偏函数)

Python高级特性

函数式编程(FunctionalProgramming)

lambda表达式

  • 函数:最大程度复用代码
    • 存在问题:如果函数很小,很短,则会造成啰嗦
    • 如果函数被调用次数少,则会造成浪费
    • 对于阅读者来说,造成阅读流程的被迫中断
  • lambda表达式(匿名函数)
    • 一个表达式,函数体相对简单
    • 不是一个代码块,仅仅是一个表达式
    • 可以有参数,逗号隔开
# lambda表达式的用法
#以lambda开头
#紧跟一定的参数
#参数后用冒号和表达式主题隔开
#没有return
stm = lambda x:100*x
print(stm(89))

>>>
8900

----
stmt = lambda x,y,z:x+y*12+z*90
print(stmt(100,34,5))

>>>
958

高阶函数

  • 把函数作为参数来使用的函数
def funA():
    print("In funA")
funB = funA
funB()

>>>
In funA
  • 函数名称是变量
  • funA和funB是指名称不一样
  • 既然时变量就可以当参数传入
# funA是一个普通函数,
def funA(n):
    return n * 100
def funC(n, f):
    return f(n)*3
print(funC(9, funA))

>>>
2700

map

  • 原意就是映射,即把集合或者列表的元素,每一个人元素都按照一定规则进行操作,生成一个新的列表或者集合
  • map函数时系统提供的具有映射功能的函数,返回值是一个迭代对象
l1 = [i for i in range(10)]
def mulTen(n):
    return n*10
l2 = map(mulTen, l1) # l2的类型是可迭代的,直接用for、循环遍历
for i in l2:
    print(i)

reduce

  • 原意是归并,缩减
  • 把一个可迭代的内容最后归并为一个结果
  • 对于作为参数的函数要求,必须有两个参数,必须有两个返回结果
  • reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
  • 需要导入functools包
from functools import reduce
def myAdd(x,y):
    return x+y
# 先把前两个参数计算,返回值再与第三个数计算,返回值再与第四个数计算......
rst = reduce(myAdd, [1,2,3,4,5,6])
print(rst)

>>>
21

filter 过滤函数

  • 过滤函数,对一组数据进行过滤,符合条件的数据会生成一个新的列表返回
  • 跟map相比较
    • 相同:都对列表的每一个元素进行操作
    • 不同:
      • map生成一个跟原来数据相对应的新列表
      • filter不一定,只要符合条件的才会进入新的数据集合
    • filter函数怎么写:
      • 利用给定函数进行判断
      • 返回值一定时布尔值
      • 调用格式:filter(f,data),f时过滤函数,data数据
# 对于一个列表,对其进行过滤,偶数组成一个新列表
def isEven(a):
    return a%2 == 0
l = [3,4,45,23,345,56,57,56,8,86,9,45,24,2]
rst = filter(isEven, l)
print([i for i in rst])

>>>
[4, 56, 56, 8, 86, 24, 2]

排序

  • 把一个序列按照给定算法进行排序
  • key:在排序前对每一个元素进行key函数运算
a = [23,43,5,65,77,68,99,732,4]
al = sorted(a, reverse = True) # reverse倒序
print(al)

>>>
[732, 99, 77, 68, 65, 43, 23, 5, 4]

-----
a = [-23, 34,54,675,78,-54,-76,3]
# 按照绝对值排序
al = sorted(a, key=abs, reverse = True)
print(al)

>>>
[675, 78, -76, 54, -54, 34, -23, 3]

-----
astr = ['dana', 'Danna','nihao','Taobao']
str = sorted(astr)
print(str)

>>>
['Danna', 'Taobao', 'dana', 'nihao']

返回函数

  • 函数可以返回具体的值
  • 也可以返回一个函数作为结果
# 函数作为返回值返回,被返回的函数在函数体内定义
def myF2():
    def myF3():
        print("In myF3")
        return 3
    return myF3
f3 = myF2()
print(type(f3))
print(f3)
print(f3())

>>>
<class 'function'>
<function myF2.<locals>.myF3 at 0x000001525EA8BC80>
In myF3
3
def myF4(*args):
    def myF5():
        rst = 0
        for n in args:
            rst += n
        return rst
    return myF5
f5 = myF4(1,2,3,4,5,6,7,8,9,0)
print(f5())

>>>
45

闭包closure

  • 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当作返回值的时候,相关参数和变量保存在返回的函数中,这种结果叫做闭包
# 闭包常见的坑
def count():
    fs = []
    for i in range(1,4):
        def f():
            return i*i
        fs.append(f)
    return fs
f1,f2,f3=count()
print(f1())
print(f2())
print(f3())
# 本来期望的是1,4,9

>>>
9
9
9
  • 造成上述状况的是,返回函数引用了变量i,i并非立即执行,而是等到三个函数都返回的时候才同意使用,此时i已经变成3,最终调用的都是3*3
  • 返回闭包是,返回函数不能引用任何循环变量
  • 解决方案:在创建一个函数,用该函数的参数绑定循环变量的当前值,无论循环变量以后如何改变,已经绑定的函数参数值不再改变
def count2():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1,4):
        fs.append(f(i))
    return fs
f1,f2,f3 = count2()
print(f1())
print(f2())
print(f3())

>>>
1
4
9

装饰器decrator

  • 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
  • 装饰器的使用,使用@语法,即每次要扩展到函数定义前使用@+函数名
import time
def printTime(f):
    def wrapper(*args, **kwargs):
        print("Time:", time.ctime())
        return f(*args, **kwargs)
    return wrapper
# 在执行hello之前,先打印时间
@printTime # 借助于@语法糖
def hello():
    print("hello world")
hello()

>>>
Time: Tue Jul 23 12:26:53 2019
hello world

----
# 手动执行装饰器
hello3 = printTime(hello)
hello3()

>>>
Time: Tue Jul 23 12:34:14 2019
Time: Tue Jul 23 12:34:14 2019
hello world

偏函数

# 新建一个函数,此函数是默认输入的字符串是16进制数字
# 把此字符串返回十进制的数字
def int16(x, base=16):
    return int(x, base)
int16("12345")

>>>
74565
  • 偏函数
  • 参数固定的函数,相当于一个由特定参数的函数体
  • functools.partial的作用是,把一个把函数某些函数固定,返回一个新函数
import functools
int16 = functools.partial(int, base=16)
print(int16("12345"))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值