最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

python基础:函数式编程高阶

XAMPP案例 admin 53浏览 0评论
函数式编程(Functional Programming)
函数式编程是一种编程风格(顾名思义)是基于函数的。
函数式编程的关键部分是高阶函数。在前两篇中关于函数作为对象的知识中我们已经简要地看到了这个想法。高阶函数将其他函数作为参数,或将其作为结果返回。

For example:

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


def add_five(x):
    return x + 5


print(apply_twice(add_five, 10))
Tips:函数apply_twice以另一个函数作为参数,并在其内部两次调用它。
纯函数(Pure Functions)
为了提高程序可读性,使用的函数要尽量没有副作用,即所谓的“纯函数”。使用纯函数的好处包括可以通过改变求值顺序实现优化,而其最重要的优势在于概念简单、测试方便。
Tips:这其实就是数学函数的方式:例如,对于x的相同值,cos(x)将始终返回相同的结果。
For example:
Pure function:
def pure_function(x, y):
    temp = x + 2 * y
    return temp / (2 * x + y)
Pure function:
some_list = []


def impure(arg):
    some_list.append(arg)
 
Tips: 上面的函数不是纯函数,因为它更改了some_list的状态。
在Python中,编写纯函数式代码要求代码的作用域为本地,具体而言,就是避免使用global语句。nonlocal语句的使用也可能对作用域产生副作用,也应留意,虽然副作用限制在一个嵌套函数里。实际上,达到这些要求并不难。可以把纯函数看作普通的Python编程实践。
图片
使用纯函数既有优点也有缺点
优点:
  • 更容易理解和测试。
  • 更加高效。一旦为输入评估了函数,就可以存储结果,并在下次需要该输入的函数时参考该结果,从而减少了调用函数的次数。这称为记忆。
  • 更容易并行运行。
缺点:
  • 它们会使原本就很简单的I/O任务复杂化,这似乎固有地具有副作用图片
  • 在某些情况下,编写纯函数也可能会更加困难。
图片
匿名函数(Lambdas)

正常创建函数(使用def)会自动将其分配给变量。这与其他对象(例如字符串和整数)的创建不同,后者可以即时创建而无需将它们分配给变量。如果函数是使用lambda语法创建的,则函数也是可能的。通过这种方式创建的函数称为匿名函数。将简单函数作为参数传递给另一个函数时,最常使用此方法。语法在下一个示例中显示,由lambda关键字,后跟参数列表,冒号以及要求值并返回的表达式组成。

def my_func(f, arg):
    return f(arg)


my_func(lambda x: 2 * x * x, 5)
Tips:Lambda函数以lambda演算而得名,lambda演算时Alonzo Church发明的一种计算模型。
用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。(简化代码量,节约内存空间)
# 计算 a + b
# func
def add(a, b):
    return a + b

print(add(1, 2))

# lambda
print((lambda a, b: a + b)(1, 2))
Tips:上面的代码,我们创建了一个标准函数和一个匿名函数,可以看到,使用lambda函数会有效减少我们的工作量!!!

dz00085Python

lambda函数可以分配给变量,并且可以像普通函数一样使用。
For example:
double = lambda x: x * 2
print(double(7))
Tips:但是,我们一般不这样做,这种情况最好用def定义一个函数。
dz85Python
map & filter
内置函数map和filter是对列表(或称为iterables的类似对象)进行操作的非常有用的高阶函数。

map
map函数以一个函数和一个可迭代对象作为参数,并返回一个将函数应用于每一参数的新的可迭代对象。
For example:
def add_five(x):
    return x + 5


nums = [11, 22, 33, 44, 55]
result = list(map(add_five, nums))
print(result)  # [16, 27, 38, 49, 60]
Tips:通过使用lambda语法,我们可以更轻松地实现相同的结果。
nums = [11, 22, 33, 44, 55]

result = list(map(lambda x: x + 5, nums))
print(result)
为了将结果转换为列表,我们使用显示转换方法list()。
 

filter
filter函数又称为函数过滤器,通过删除与为此不匹配的项(返回布尔值的函数)来过滤可迭代项。
For example:
nums = [11, 22, 33, 44, 55]
res = list(filter(lambda x: x % 2 == 0, nums))
print(res)
# [22, 44]  
可以看到,通过该方式我们可以筛选出我们想要的内容。
Tips:与map一样,如果要打印结果,则必须将结果显式转换为列表。
图片

递归

1. 什么是递归函数?

如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。

2. 递归特点:

  <1>自己调用自己

  <2>要有函数出口

3. 递归实例

1、 用递归实现1-100的累加和

(事实上用循环会更简单,仅作递归的了解)

# 1-100的和
def sum_numbers(num):
    # 如果是1,直接返回1 --函数出口
    if num == 1:
        return 1
    # 如果不是1,重复执行累加并返回结果
    return num + sum_numbers(num - 1)


num = int(input('please input a num:'))
sum_result = sum_numbers(num)
print(sum_result)

结果显示:

dz0000085Python

事实上,关于递归,另外一个例子似乎更加典型

2 、计算阶乘 n! = 1 * 2 * 3 * … * n

# 使用递归来完成阶乘
def cal_num(num):
    if num >= 1:
        result = num * cal_num(num - 1)
    else:
        result = 1
    return result


ret = cal_num(3)
print(f'递归计算阶乘结果:{ret}')
简单梳理一下:

dz000085Python

写一些基础代码似乎并不会经常用到递归,不过还是希望你把它的核心掌握住。
 

LEGB规则

Python 在查找“名称”时,是按照 LEGB 规则查找的:

Local–>Enclosed–>Global–>Built in

 

  • Local 指的就是函数或者类的方法内部
  • Enclosed 指的是嵌套函数(一个函数包裹另一个函数,闭包)
  • Global 指的是模块中的全局变量
  • Built in 指的是 Python 为自己保留的特殊名称。

如果某个 name 映射在局部(local)命名空间中没有找到,接下来就会在闭包作用域 (enclosed)进行搜索,如果闭包作用域也没有找到,Python 就会到全局(global)命名空间中进行查找,最后会在内建(built-in)命名空间搜索 (如果一个名称在所有命名空间 中都没有找到,就会产生一个 NameError)。

写在最后

本节给大家介绍了Python语法中的高阶函数和递归函数。是实际应用中的高频语法!!!勤能补拙是良训,希望大家还是动手做一做,有问题可以私信我,欢迎交流和提出您的宝贵意见。

你要偷偷学Python,然后惊艳所有人。

转载请注明:XAMPP中文组官网 » python基础:函数式编程高阶