Python函数和函数嵌套、闭包、递归、匿名详细讲解(三)

  • Post author:
  • Post category:python



目录


一、python函数


二、函数嵌套


三、函数闭包和递归


四、函数匿名


一、python函数


概述

Python 包含许多预定义的内置函数,最终用户可以通过简单地调用它们来使用它们。这些功能不仅使程序员的工作更轻松,而且有助于建立一个通用的编码环境。在本教程中,您将了解 Python 的三个最强大的函数:map()、filter() 和 reduce()。

函数式编程的三大支柱是 map、filter 和 reduce 函数。虽然 Python 不完全是一种函数式编程语言,但它确实有很多特性使它如此。本文讨论了 Python 中的 map、filter 和 reduce 函数,以及它们如何对应于函数式编程原则。


函数式编程

使用函数来定义计算的编程范式称为函数式编程。不可更改状态的概念是函数式编程的关键定义特征之一。

计算是通过命令式编程中的语句完成的,这可以说是您已经熟悉的最流行的编程范式。这些命令会影响变量的值,从而影响执行后的计算状态。例如,for 循环可以重复执行一条语句,每次更改变量的值,如下所示:

counter = 0
for i in range(10):
    counter += 1
复制代码

在循环的每次迭代中,计数器的值每次增加 1 时,计算状态都会发生变化,使其更接近结束状态。

在我们讨论 Python 中的“map()”、“filter()”和“reduce()”函数的示例之前,我们需要了解另一个概念:高阶函数。


高阶函数

在函数式编程中,高阶函数是我们定义计算的主要工具。这些是将函数作为参数并返回函数作为结果的函数。Reduce()、map() 和 filter() 是 Python 中最有用的三个高阶函数。当与更简单的功能配对时,它们可用于执行复杂的操作。

下面的代码示例演示了一个高阶函数。print greeting() 接受两个参数:函数 f 和名称 n,并返回调用 f 的结果。(n)。

def greet(name):
    return "Hello, {}!".format(name)
复制代码
def print_greeting(f, n):
    print(f(n))
复制代码


匿名函数

我们在上一节中看到了一个将另一个函数作为参数的函数示例。函数 map()、filter() 和 reduce() 都做同样的事情:它们每个都接受一个函数和一个元素列表,然后返回将函数应用于列表中每个元素的结果。

如前所述,Python 具有内置函数,如 map()、filter() 和 reduce()。Python 的函数式编程特性是通过这些函数启用的。在函数式编程中,唯一决定输出的因素是传入的输入。这些函数可以接受任何其他函数作为参数,也可以作为参数传递给其他函数。现在让我们更详细地了解这些函数中的每一个。

我们有三个主要功能:

  1. 地图()
  2. 筛选()
  3. 减少()

1.map() 函数:

map() 函数是一个高阶函数。如前所述,此函数接受另一个函数和一系列“可迭代对象”作为参数,并在将函数应用于序列中的每个可迭代对象后提供输出。它具有以下语法:


语法:

映射(函数,可迭代对象)

该函数用于定义一个表达式,然后将其应用于“可迭代对象”。用户定义函数和 lambda 函数都可以发送到 map 函数。

用户定义的函数可以发送到 map() 方法。用户或程序员是唯一可以更改这些函数参数的人。

例子

def function(a): 
    return a*a 
x = map(function, (1,2,3,4)) #x是地图对象
print(x) 
print(set(x))
复制代码

输出

{16, 1, 4, 9}
复制代码

x 是一个地图对象,如您所见。接下来显示 map 函数,它以“function()”为参数,然后将“a * a”应用于所有 ‘iterables’。结果,所有可迭代对象的值在返回之前都与它们自身相乘。

让我们看看如何在 map() 方法中使用 lambda 函数。


map() 函数中的 Lambda:

没有名称的函数称为 lambda 函数。这些函数经常用作其他函数的输入。让我们尝试将 Lambda 函数集成到 map() 函数中。

例子

tup= (5, 7, 22, 97, 54, 62, 77, 23, 73, 61)
newtuple = tuple(map(lambda x: x+3 , tup)) 
print(newtuple)
复制代码

输出

(8, 10, 25, 100, 57, 65, 80, 26, 76, 64)
复制代码

2.filter()函数:

filter() 函数用于生成在调用该函数时返回 true 的值的输出列表。它具有以下语法:


语法:

过滤器(函数,可迭代对象)

这个函数和 map() 一样,可以接受用户定义的函数和 lambda 函数作为参数。

例子

def func(x):
    如果 x>=3: 
        return x 
y = filter(func, (1,2,3,4))   
print(y) 
print(list(y))
复制代码

输出

[3, 4]
复制代码

如您所见,y 是过滤器对象,列表是条件 (x>=3) 的真值集合。


filter() 函数中的 Lambda:

要检查的条件由作为参数提供的 lambda 函数定义。

例子

y = filter(lambda x: (x>=3), (1,2,3,4))
打印(列表(y))
复制代码

输出

[3, 4]
复制代码

3.reduce() 函数:

顾名思义,reduce() 函数将提供的函数应用于“可迭代对象”并返回单个值。


语法:

reduce(function, iterables)

该函数指定在这种情况下应将哪个表达式应用于“可迭代对象”。必须使用功能工具模块来导入此功能。

例子

from functools import reduce

reduce(lambda a,b: a+b,[23,21,45,98])
复制代码

输出

187
复制代码

前面示例中的 reduce 函数将列表中的每个可迭代对象一一添加并返回单个结果。

Python 函数 map()、filter() 和 reduce() 都可以一起使用。

二、函数嵌套

1.python函数嵌套

在工作中遇到了函数嵌套:即一个函数里面,再定义一个函数。为什么要在函数里再定义一个函数?这和装饰器有什么区别? 别急!来上代码:

def fun1(a):
    def fun2(b):
        c = a*b
        print(c)
    return fun2
fun2 = fun1(2)
fun2(3)
#  fun1(2)(3)
复制代码

一个函数在另外一个函数的里面,外层的函数返回的是里层函数。也就是函数本身被返回了,返回的是函数(就像C语言返回指向函数的指针一样)。

def fun1(a):
    d = 5
    def fun2(b):
        res = a*b*d
        print(res)
    def fun3(c):
        res = a**c-d
        print(res)
    return fun2,fun3
复制代码

返回的函数还可以访问它的定义所在的作用域,也就是它带着它的环境信息。如fun2、fun3是可访问变量d的。

2.装饰器

其实,上面函数嵌套的最外层函数名字就是装饰器名称

def fun4(fun):
    def fun5():
        print("进入装饰器,准备修改函数")
        fun()
        print("修改函数完毕,准备离开装饰器")
    return fun5
@ fun4
def fun():
    print("我是将要被修改的函数")
fun()
print(fun.__name__)
output:fun5
# 此时fun函数的名字和注释文档(docstring)被重写了
复制代码

当不希望函数名不被重写时,使用functiontool

from functiontool import wraps
def fun4(fun):
    @wraps(fun)
    def fun5():
        print("进入装饰器,准备修改函数")
        fun()
        print("修改函数完毕,准备离开装饰器")
    return fun5
@ fun4
def fun():
    print("我是将要被修改的函数")
fun()
print(fun.__name__)
output:fun
复制代码

@wraps(fun)装饰器像普通函数一样

def fun6(str = "abcde"):
    def fun7(fun):
        @wraps(fun)
        def fun8():
            print("进入装饰器,准备修改函数")
            s = fun()
            print(s+str)
            print("修改函数完毕,准备离开装饰器")
            return fun()
        return fun8
    return fun7
@fun6("我是新的参数")
def fun():
    return "我是将要被修改的函数"
fun()
# 新参数传进去了

三、函数闭包和递归

1.闭包

简单来说就是一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行。这样的一个函数我们称之为闭包。

小知识点:

函数引用:

def fun1():
        print('this is fun1')

fun1()      #这样可以调用
fun = fun1    #赋值   能够让fun和fun1指向同一片内存空间
fun()         #通过赋值之后的也可以调用函数
复制代码

引入的话看这个例子:

def fun1():
        print('this is fun1')
        def fun2():
                print('this is fun2')
        fun2()        #如果要使用函数里嵌套的函数fun2,就要调用,这样在调用fun1的时候才会使用到内层函数fun2
fun1()     
复制代码

仔细看看,现在我要把这个例子变成闭包了:::

def fun1():
        print('this is fun1')
        def fun2():
                print('this is fun2')
        return fun2     #在函数fun1下面返回里面函数的名字
fun1() ()
复制代码

注意:::

return fun2相当于fun1()里面有了fun2()

现在如果调用fun1()的时候直接fun1(),就相当于fun1() = fun2 。这样还是只执行了fun1()。

所以等号两边同时加个括号,看可以把fun2()函数也执行了:fun1()() = fun2()

升华一下啦:::!!!

内嵌函数:

闭包是函数里面嵌套函数,外层函数返回里层函数的函数名,这种情况称为闭包。

闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用

闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁

例子:

def zhangxinyi():
    x = 2000

    def wuhan(y):
        return y + x

    return wuhan

print(zhangxinyi()(1000))

# 输出为:3000
复制代码

根据闭包函数中引用的自由变量的一些特性,闭包的应用场景还是比较广泛的。后面会有文章介绍其应用场景之一——单例模式,后面可以讲讲~

2.递归:

函数自己调用自己,如果不做限制,就一直调用自己,直到超出最大的递归深度而报错。

引入例子:

def fun():
        print('this is fun')
        fun()

fun()
复制代码

下面讲到正题:::!!!

阶乘factorical::: 5! = 5

4

3

2

1

例子:

def fun(n):
        if n == 1:
                return 1
        return n*fun(n-1)

print(fun(5))
复制代码

解释下:::

#n

fun(n-1)

#fun(5)返回5

fun(4)

#fun(4)返回4

fun(3)

#fun(3)返回3

fun(2)

#fun(2)返回2*fun(1)

#fun(1)返回 1 #如果不加限制,就会一直往下递归,所以应该加个限制,就是上面的if语句

在来个例子:::

#递归求高斯求和

def sum(n):
    if n == 1:
        return 1
    return n + sum(n-1)
print(sum(100))

#n = 100  return 100 + sum(99)
#n = 99   return 99  + sum(98)
#n = 98   return 98  + sum(97)
#...
#n = 1    return 1

四、函数匿名

1.n匿名函数

语法:函数名 = lambda 形参:返回值

匿名函数不需要return来返回值,表达式本身就是返回值

funa = lambda a, b: a + b

print(funa(5, 6))

在字符串中取值,添加进空列表中

st = ‘python’

li = []

print(st[2], st[4])

li.append(st[2])

li.append(st[4])

print(li)

#匿名函数写法:

x 这个形参代表要操作的字符串

func = lambda x: [x[2],x[4]]

因为匿名函数表达式就是返回值,所以需要返打印

有形参,需要在()中传值

print(func(‘lupan’))

三目运算: 为真的结果 if 条件 else 为假的结果

a = 1

b = 2

print(a) if a > b else print(b)

匿名函数

we = lambda a, b: a if a > b else b

print(we(10, 40))

今天先更新到这里了,喜欢博主的麻烦点下关注,点赞,收藏,接下来会持续更新

B站最牛的Python自动化测试框架全栈测试开发实战项目入门到精通,涨薪必备教程!!!



版权声明:本文为m0_68405758原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。