zoukankan      html  css  js  c++  java
  • Python函数篇(2)-递归函数、匿名函数及高阶函数(已更新)

    1.全局变量和局部变量

      一般定义在程序的最开始的变量称为函数变量,在子程序中定义的变量称为局部变量,可以简单的理解为,无缩进的为全局变量,有缩进的是局部变量,全局变量的作用域是整个程序,而局部变量的作用域是子程序内部,当程序运行时,首先会找程序内部有没有局部变量,如果有,则调用,如果没有,才会去调用全局变量。如下:

    name="czp"            #全局变量
    def func():
        name="czp1"         #局部变量
        print(name)
    func()
    运行结果:
    czp1              调用func()函数,程序会先在函数内部找有没有name这个变量,如果有,就会调用该name的值,而如果没有定义局部变量的话,函数会去找全局name。

      可以通过global关键字,通过局部变量修改全局变量,如下所示:

    name="czp"          #定义全局变量
    def func():
        global name       在函数内部,通过global关键字,通过局部变量修改全局变量的值
        name="czp1"
        print(name)
    func()            打印局部变量中name的值
    print(name)         打印全局变量中name的值
    运行结果:
    czp1
    czp1             在运行结果中可以明显看出,通过global,在定义局部变量的同时,也修改了全局变量的值

      global与nonlocal的区别:

      python引用变量的顺序: 当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量

      global关键字用来在函数或局部作用域中使用全局变量,并通过glabal关键字在局部作用域中修改全局变量(一般不推荐这么做)

      nonlocal关键字用来在函数或局部作用域使用外层(非全局)变量。

    2.递归函数

      在一个函数的内部,可以调用其他的函数,如果某一个函数在内部调用的函数仍然是自身,这个函数就可以称为递归函数。

    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关键字定义,通常我们定义一个函数用这种形式:

    def calc(x):
        return x+1
    print(calc(2))
    运行结果:
    3

      而上段代码 用匿名函数使用的话,就可以使用如下的方式,通过lambda关键字,传入一个形参x,用冒号隔开,后面加入return的值。

    res=lambda x:x+1
    print(res(2))
    运行结果:
    3

      匿名函数单独这么用意义不大,但是和其他函数一起用的时候,功能就显现的很明显了。如下面的例子

    res=map(lambda x:x**2,[2,4,6,])
    for i in res:
        print(i)
    运行结果:
    4
    16
    36

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

    4.高阶函数

      高阶函数的特点如下:1)函数接收的参数是一个函数 ;2)函数的返回值是一个函数

    将函数作为参数传给另一个函数
    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
    将函数作为另一个函数的返回值
    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,然后打印出来,这个程序可以这样写:

    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),或者更高级一点,我们在定义一个函数:

    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+上面提到的匿名函数,可以很好的完成这样的需求:

    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会进行计算,返回一个值

    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
    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,返回非空的项。

    name=["czp","cc","zp1"]
    print(list(filter(lambda n:n.endswith("c"),name)))    通过匿名函数判断条件,返回值为真,就会打印成列表的形式
    运行结果:
    ['cc']

       在下一篇文章中,我会介绍其他的常用内置函数

  • 相关阅读:
    获得Coclor的色值(小技巧)
    如何禁止IIS缓存静态文件(png,js,html等)(转)
    风投最关心的问题
    Repeater一行显示数据库中多行表记录
    c# int Int32 Int64 的区别
    动车实名制了
    学习,积累,10000小时定律
    映射路由器到内网ip和端口
    《轮环》故事大纲整理
    .Net读取xlsx文件Excel2007
  • 原文地址:https://www.cnblogs.com/Chen-Zhipeng/p/8005627.html
Copyright © 2011-2022 走看看