Python教程:函数式编程

Python函数式编程是一种编程范式,它强调使用纯函数来处理数据。函数是程序的基本构建块,并且尽可能避免或最小化可变状态和副作用。在函数式编程中,函数被视为一等公民,可以像值一样传递和存储。本教程将介绍如何使用Python进行函数式编程,并提供一些示例。

1.纯函数

纯函数是指不产生副作用的函数,即只依赖于输入参数并返回输出结果,而不修改任何外部状态。纯函数通常易于测试、可组合和并发执行。例如,下面是一个非纯函数:

total = 0

def add(n):
    global total
    total += n
    return total

这个函数会修改total全局变量,因此是有副作用的。相反,下面是一个纯函数:

def add(n):
    return n + 1

这个函数只依赖于输入参数并返回输出结果,没有任何副作用。

2.函数是一等公民

在函数式编程中,函数是一等公民。这意味着函数可以像其他数据类型一样传递给其他函数,也可以从其他函数中返回。例如:

def apply(func, arg):
    return func(arg)

def double(x):
    return x * 2

print(apply(double, 5)) # 输出 10

在这个例子中,我们定义了一个名为apply的函数,它接受两个参数:一个函数和一个参数。它将这个参数传递给这个函数并返回结果。

3.高阶函数

高阶函数是指接受一个或多个函数作为参数和/或返回一个函数的函数。Python提供了许多内置的高阶函数,如mapfilterreduce。例如:

# map
def square(x):
    return x ** 2

numbers = [1, 2, 3, 4, 5]
squares = list(map(square, numbers))
print(squares) # 输出 [1, 4, 9, 16, 25]

# filter
def is_even(x):
    return x % 2 == 0

numbers = [1, 2, 3, 4, 5]
evens = list(filter(is_even, numbers))
print(evens) # 输出 [2, 4]

# reduce
from functools import reduce

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

numbers = [1, 2, 3, 4, 5]
sum = reduce(add, numbers)
print(sum) # 输出 15

在这个例子中,我们定义了三个函数:squareis_evenadd。然后,我们使用内置的高阶函数mapfilterreduce来对数字列表进行操作。

4.Lambda表达式

Lambda表达式是一种匿名函数,可以用来定义简单的函数。它们通常在需要一个函数作为参数的地方使用。例如:

numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
print(squares) # 输出 [1, 4, 9, 16, 25]

evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # 输出 [2, 4]

在这个例子中,我们使用Lambda表达式来定义mapfilter函数的函数参数。

更多教程:PoyCode编程指南[1]

5.偏函数

偏函数是指通过部分设置参数来创建新函数的过程。在Python中,我们可以使用functools.partial函数来实现偏函数。偏函数是一种指定部分参数的函数。例如,假设有一个函数:

def power(base, exponent):
    return base ** exponent

如果要计算2的平方和立方,可以这样实现:

print(power(2, 2))
print(power(2, 3))

输出:

4
8

使用偏函数可以更方便地计算多个指数。例如:

from functools import partial

square = partial(power, exponent=2)
cube = partial(power, exponent=3)

print(square(2))
print(cube(2))

输出:

4
8

这里使用了functools.partial函数将power函数的exponent参数固定为23,从而创建了两个新的函数squarecube

6.函数组合

函数组合是指将多个函数组合成一个函数。例如,假设有两个函数:

def add1(n):
    return n + 1

def double(n):
    return n * 2

现在要实现一个新函数,将add1double组合起来,可以这样实现:

def compose(f, g):
    return lambda x: f(g(x))

add1_double = compose(add1, double)
print(add1_double(3))

输出:

7

这个函数首先将输入参数3传递给double函数,然后将其结果6传递给add1函数,最终得到7

上一篇教程:Python数据结构:列表、元组、字典、集合[2]

7.不可变性

函数式编程鼓励不可变性,尽量减少或避免可变状态和副作用。这可以通过使用元组、冻结集合和不可变对象来实现。例如:

# 元组
person = ('John', 25)
name, age = person

# 冻结集合
my_set = frozenset([1, 2, 3])

# 不可变对象
from collections import namedtuple

Person = namedtuple('Person', ['name', 'age'])
person = Person(name='John', age=25)

在这个例子中,我们使用元组、冻结集合和不可变对象来创建不可变数据结构。

8. 尾递归优化

尾递归是指函数的最后一个操作是它自己的递归调用。这可以通过迭代实现,并且可以避免堆栈溢出错误。Python没有尾递归优化,但可以使用生成器和迭代器来模拟。尾递归优化是一种技术,它可以将递归函数的调用栈优化为迭代循环,从而减少内存占用和提高程序性能。

在 Python 中实现尾递归优化有两种方法:

  1. \1. 使用 sys.setrecursionlimit() 函数增加最大递归深度。
  2. \2. 实现一个尾递归函数,并使用一个 while 循环替换递归调用。

以下是一个简单的例子:

import sys

sys.setrecursionlimit(10000)

def factorial(n, acc=1):
    if n == 0:
        return acc
    else:
        return factorial(n-1, acc*n)

def tail_recursion_factorial(n, acc=1):
    while n > 0:
        n, acc = n-1, acc*n
    return acc

在这个例子中,我们定义了两个函数:factorialtail_recursion_factorialfactorial 是一个正常的递归函数,而 tail_recursion_factorial是一个尾递归函数。

如果使用 factorial(1000) 这样的参数调用 factorial 函数,将会产生 RecursionError,因为默认情况下 Python 的最大递归深度为1000。为了解决这个问题,我们增加了最大递归深度并重新运行代码。

使用 tail_recursion_factorial(1000) 来调用 tail_recursion_factorial 函数,则不会出现RecursionError,因为该函数被优化为迭代循环。

需要注意的是,尾递归优化并不总是有效,因为有时候需要保留函数调用栈以便于在返回时执行一些操作。此外,在 Python 中默认情况下并没有进行尾递归优化,因此需要手动实现它。

在这里插入图片描述

9.总结

Python函数式编程是一种编程范式,它的核心思想是将计算视为数学函数的运算,并且避免使用可变状态和副作用。

第一步是理解函数是什么。在函数式编程中,函数被认为是“一等公民”,这意味着它们可以像任何其他数据类型一样传递和操作。因此,函数通常会接受输入并返回输出,而不会修改状态或影响外部环境。

然后,我们需要了解Python中的lambda表达式。Lambda表达式是一种匿名函数,它可以在需要时方便地定义和调用。它的语法类似于“lambda arguments: expression”,其中arguments是参数列表,expression是函数体。

接下来是高阶函数。在函数式编程中,高阶函数是指接受一个或多个函数作为参数的函数,或者返回一个新函数的函数。例如,map()函数可以接受一个函数和一个序列,并返回一个新序列,其中每个元素都是通过应用给定函数得到的结果。

还有一个重要的概念是闭包。闭包是指一个函数内部定义的函数,它可以访问其外部函数的变量和参数。这使得我们可以创建一些特殊的函数,例如currying和partial functions。

此外,函数式编程还涉及到一些常见的函数,例如filter()、reduce()和sorted()。这些函数可以帮助我们在Python中进行函数式编程。

最后,我们需要了解如何避免使用可变状态和副作用。这意味着我们应该尽可能避免修改对象的状态或影响外部环境。相反,我们应该尝试编写纯函数,这些函数只依赖于其输入,并且不会修改状态或引起副作用。

总之,在Python中进行函数式编程需要掌握lambda表达式、高阶函数、闭包以及避免使用可变状态和副作用等概念。通过这些技术,我们可以创建更具可读性、可维护性和可重用性的代码。

关于Python学习指南

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取保证100%免费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值