Python函数篇 -递归函数、匿名函数及高阶...

本文详细探讨了全局变量与局部变量的区别,递归函数的工作原理,匿名函数的应用场景,以及高阶函数的概念。同时,深入介绍了map、reduce和filter三个内置函数的功能与使用方法。

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

1.全局变量和局部变量

  一般定义在程序的最开始的变量称为函数变量,在子程序中定义的变量称为局部变量,可以简单的理解为,无缩进的为全局变量,有缩进的是局部变量,全局变量的作用域是整个程序,而局部变量的作用域是子程序内部,当程序运行时,首先会找程序内部有没有局部变量,如果有,则调用,如果没有,才会去调用全局变量。如下:
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
8
9
复制代码
name = "czp"              #全局变量
def func ( ) :
     name = "czp1"           #局部变量
     print ( name )
func ( )
运行结果:
czp 1               调用func ( ) 函数,程序会先在函数内部找有没有 name 这个变量,如果有,就会调用该 name 的值,而如果没有定义局部变量的话,函数会去找全局 name
复制代码


 

  可以通过global关键字,通过局部变量修改全局变量,如下所示:
[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
复制代码
name = "czp"            #定义全局变量
def func ( ) :
     global name        在函数内部,通过 global 关键字,通过局部变量修改全局变量的值
     name = "czp1"
     print ( name )
func ( )             打印局部变量中 name 的值
print ( name )          打印全局变量中 name 的值
运行结果:
czp 1
czp 1              在运行结果中可以明显看出,通过 global ,在定义局部变量的同时,也修改了全局变量的值
复制代码


 

  global与nonlocal的区别:
  python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量
  global关键字用来在函数或局部作用域中使用全局变量,并通过glabal关键字在局部作用域中修改全局变量(一般不推荐这么做)
  nonlocal关键字用来在函数或局部作用域使用外层(非全局)变量。

2.递归函数

  在一个函数的内部,可以调用其他的函数,如果某一个函数在内部调用的函数仍然是自身,这个函数就可以称为递归函数。
[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
复制代码
def calc ( n ) :
     print ( n )
     if int ( n / 2 ) = = 0 :
         return n
     return calc ( int ( n / 2 ) )         在calc函数中,反复调用calc自身,这样的函数就是递归函数
calc ( 10 )
运行结果:
10
5
2
1
复制代码


 

  注意:在递归函数中,并不是可以让自身永远的循环下去,递归函数中必须定义一个明确的结束条件,每进行更深一次的递归,解决问题的规模必须要较上一层有所减少,
  递归函数常用来进行二分查找。。

3.匿名函数

  匿名函数其实就是不需要指定显示的函数。用lambda关键字定义,通常我们定义一个函数用这种形式:
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
5
def calc ( x ) :
     return x + 1
print ( calc ( 2 ) )
运行结果:
3

 

  而上段代码 用匿名函数使用的话,就可以使用如下的方式,通过lambda关键字,传入一个形参x,用冒号隔开,后面加入return的值。
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
res = lambda x : x + 1
print ( res ( 2 ) )
运行结果:
3

 

  匿名函数单独这么用意义不大,但是和其他函数一起用的时候,功能就显现的很明显了。如下面的例子
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
5
6
7
8
9
复制代码
res = map ( lambda x : x * * 2 , [ 2 , 4 , 6 , ] )
for i in res :
     print ( i )
运行结果:
4
16
36
复制代码


 

  我会在接下来写内置方法的时候具体的展示出使用匿名函数的好处。

4.高阶函数

  高阶函数的特点如下:1)函数接收的参数是一个函数 ;2)函数的返回值是一个函数
[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
复制代码
将函数作为参数传给另一个函数
def foo ( n ) :   
     print ( n )
def bar ( name ) :
     print ( "my name is %s" % name )
print ( foo ( bar ( "尼古拉斯赵四" ) ) )
运行结果:
my name is 尼古拉斯赵四
None
None                    返回两个None,因为在foo()和bar()函数中我没有定义retturn。默认返回None
复制代码


 

[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
复制代码
将函数作为另一个函数的返回值
def bar ( ) :
     print ( "from bar" )
def foo ( ) :
     print ( "from foo" )
     return bar
foo ( ) ( )
运行结果:
from foo
from bar
复制代码



4.内置函数

  首先我先介绍3个比较重要,也是比较常用的内置函数,map;reduce,filter3个内置函数

  1.map:

    将函数作用于seq中的每一个元素,并将所有的调用的结果作为一个list返回。
    模拟一下这个需求:有一个列表[1,2,3,4],我要让列表中的每一个元素自增1,然后打印出来,这个程序可以这样写:
[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
复制代码
name = [ 1 , 2 , 3 , 4 ]        
res = []                  定义一个空列表,用来接收自增一后的值
def calc ( array ) :
     for i in array :            使用 for 循环,遍历传入列表中的每一个元素
         res.append ( i + 1 )         
     return res
print ( calc ( name ) )
运行结果:
[ 2 , 3 , 4 , 5 ]
复制代码


 

  那如果 我想要的需求是让列表自减1,自乘呢,难道要把这段代码重复写一段,只是改一句res.append(i-1),或者更高级一点,我们在定义一个函数:
[AppleScript]  纯文本查看  复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
复制代码
def increase ( x ) :
     return x -1                定义一个自减 1 的函数
name = [ 1 , 2 , 3 , 4 ]
res = []
def calc ( func , array ) :            在这里定义两个形参,一个用来传入函数increase,一个用来传入列表 name
     for i in array :
         res.append ( increase ( i ) )     
     return res
print ( calc ( increase , name ) )
运行结果:
[ 0 , 1 , 2 , 3 ]
复制代码


 

  更高级一点呢?我们用map+上面提到的匿名函数,可以很好的完成这样的需求:
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
name = [ 1 , 2 , 3 , 4 ]
print ( list ( map ( lambda x : x + 1 , name ) ) )
运行结果:
[ 2 , 3 , 4 , 5 ]

 

  ok,上面写了那么多,两行代码搞定。

  2.reduce:

  reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。可以简单的理解为,map接受一个列表,返回的仍然是一个列表,而reduce会进行计算,返回一个值
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
5
from functools import reduce                  必须导入reduce方法
name = [ 1 , 2 , 3 , 4 ]
print ( ( reduce ( lambda x , y : x + y , name ) ) )       函数必须传入两个参数,然后传入 list
运行结果:
10

 

  reduce还有一个默认参数 ,就是可以在list后再传入一个初始值。

 def reduce(function, sequence, initial=None)    这个初始值默认为None

[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
5
from functools import reduce
name = [ 1 , 2 , 3 , 4 ]
print ( ( reduce ( lambda x , y : x + y , name , 5 ) ) )      还是上面的例子,我在最后加了初始值 5 (默认是none)
运行结果:
15


  3.filter

   filter读入iterable所有的项,判断这些项对function是否为真,返回一个包含所有为真的项的迭代器。如果function是None,返回非空的项。
[AppleScript]  纯文本查看  复制代码
?
1
2
3
4
name = [ "czp" , "cc" , "zp1" ]
print ( list ( filter ( lambda n : n.endswith ( "c" ) , name ) ) )     通过匿名函数判断条件,返回值为真,就会打印成列表的形式
运行结果:
['cc']

{:8_507:}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值