python函数式编程FP---学习笔记

这篇博客主要介绍了Python的函数式编程概念,包括高阶函数如map、reduce、filter和sorted的使用,返回函数、闭包、匿名函数、装饰器以及偏函数的讲解。通过实例展示了如何在Python中应用这些函数式编程技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是跟着廖老师的学习教材学习

函数式编程FP

函数是把一段能够实现某种特定功能的代码取了一个名字,在这之后调用这个名字即可实现功能的一种封装。把一个复杂任务通过层层函数调用简单化。
函数式编程——Functional Programming能够调用多个函数来实现功能。
函数式编程是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,而python允许使用变量,因此python不是纯函数式编程语言。
在这里插入图片描述

高阶函数

函数名也是变量,若把一些内置函数定义成数值,那么就会丧失原有功能。

>>> str = 10
>>> str(-10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

可以使用del str来恢复pow函数。当然最好还是重启python交互环境。
函数式编程的参数可以为函数`

def add(x, y, f):
    return f(x) + f(y)

print(add(-5, 6, str))
-56

map/reduce

map

map() 函数语法:
map(function, iterable)
map作用在于把iterable内的每个元素都调用一次function,返回每次function返回值组成的iterator.
map接收两个参数,一个是函数,另一个是可迭代对象(比如list,tuple),map结果返回一个iterator(惰性序列),因此我们可以通过list()函数来把整个序列计算出来返回一个list,也可以巧妙运用list的append方法生成一个新的list.

reduce

reduce() 函数语法:
reduce(function, iterable[, initializer])
initializer为可选参数。
有别于map的是
1.reduce中的function必须接受两个参数,把结果当做新参数再与序列下一个元素放入function进行计算。最简单的例子就是sum除了内建函数还可以这样实现

from functools import reduce
def add(x,y):
    return x+y
print(reduce(add,range(0,10)))

通过匿名函数lambda,代码还能进一步简化

from functools import reduce
print(reduce(lambda x,y:x+y,range(0,10)))

filter

filter()也就是过滤函数,与map一样也接受一个函数和序列,也返回一个Iterator
案例:筛选1到200的回数(从左往右和从右往左都是一样的数)

def huishu(n))
	return n==int(str(n)[::-1])

sorted

sorted()是排序函数,可以接受一个key函数来自定义排序,key作用于每一个字符。
案例:对一组表示学生名字和成绩的tuple按照名字排序以及按成绩排序。

L = [('Bob', 75), ('Adam', 92), ('Bart', 66)]
def by_name(t):
	return t[0]
def by_grade(h):
	return h[-1]
L2 = sorted(L, key=by_name)
L3 = sorted(L, key=by_grade)

返回函数

高阶函数可以把函数作为返回值。
比如定义一个求和函数:

>>> def calc_sum(num_list):
    s = 0
    for i in num_list:
        s += i
    return s

倘若我们不需要立即求和,而是放在后面代码中根据需要再计算(ps:在我看来相对于一个小括号包裹了该函数),我们可以返回求和的函数而非计算结果。

>>> def lazy_calc_sum(num_list):
    def calc_sum():
        s = 0
        for i in num_list:
            s += i
        return s
    return calc_sum

>>> f_lazy = lazy_calc_sum([1,2,3,4])
>>> f_lazy
<function lazy_calc_sum.<locals>.calc_sum at 0x0000003B8D25A2D8>
>>> f_lazy()
10

在这之中调用lazy_calc_sum()返回的是calc_sum(),唯有调动f_lazy时才是真正计算结果。
注:哪怕实例调用同一个函数,且参数一样,它的返回函数都是一个新的函数。也就是


>>> f1 = lazy_calc_sum([1, 3, 5, 7, 9])
>>> f2 = lazy_calc_sum([1, 3, 5, 7, 9])
>>> f1==f2
False
>>>print(id(f1))
140496661629400
>>>print(id(f2))
140496433033288

闭包

关于闭包的知识参考了一位博主的文章
链接:原文

如果一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行。这样的一个函数我们称之为闭包。
示例:

def outer():
    a = 6
    def inner():
        b = 8
        print(a)
        print(b)
    return inner

if __name__ == '__main__':
    res = outer()
    res()

执行结果:

>>>6
>>>8

自由变量a作为outer()的局部变量被内部函数引用。而当a在内部函数以局部变量定义时,就不存在闭包了

def outer():
    a = 6
    def inner():
        b = 8
        a += 1
        print(a)
        print(b)
    return inner

if __name__ == '__main__':
    res = outer()
    res()

执行函数会报错:UnboundLocalError: local variable 'a' referenced before assignment

局部变量在某种程度上优先级是大于全局变量的。

匿名函数

  1. Python用lambda语法定义匿名函数
  2. lambda只需用表达式而无需申明
  3. lambda没有函数名
  4. 在定义时直接被调用,冒号后面的表达式有且只能有一个
  5. 自带return

装饰器

本质上,decorator是一个返回函数的高阶函数。在代码运行期间增加其功能,不会修改该函数定义。
定义装饰器的时候用def,调用的时候须用@.python内置的functools.wraps装饰器可以把原始函数的__name__等属性复制到wrapper()函数中。
案例:设计dectorator,打印该函数执行时间。

import time
import functools


def metric(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        start = time.time()
        func(*args, **kw)  # 需要先运行一下函数,记录开始时间和结束时间。
        end = time.time()
        print('%s executed in %s ms' % (func.__name__, (end - start)))
        return func(*args, **kw)

    return wrapper


@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y;


@metric
def slow(x, y, z):
    time.sleep(0.1234)
    return x * y * z;


f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
    print('测试失败!')
elif s != 7986:
    print('测试失败!')

偏函数

此偏函数不等同于数学上的偏函数,用于把一个函数的某些参数设定默认值,返回一个新的函数。
案例:

import functools
sorted2 = functools.partial(sorted,key=abs)
print(sorted2([1,-3,-4]))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值