zoukankan      html  css  js  c++  java
  • 函数-递归调用、匿名

    一、什么是递归调用

    递归调用:在函数调用过程中,直接或间接地调用了函数本身,这就是函数的递归调用
    1.递归的优点

    递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

    使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000)

    2.递归的缺点

    解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

    尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

    3.递归案例

    
    
    #阶乘计算
    def fact(n):
        if n==1:
            return 1
        return n * fact(n - 1)
    
    分析
    ===> fact(5)
    ===> 5 * fact(4)
    ===> 5 * (4 * fact(3))
    ===> 5 * (4 * (3 * fact(2)))
    ===> 5 * (4 * (3 * (2 * fact(1))))
    ===> 5 * (4 * (3 * (2 * 1)))
    ===> 5 * (4 * (3 * 2))
    ===> 5 * (4 * 6)
    ===> 5 * 24
    ===> 120
    

    4.二分法

    #二分法
    l = [1, 2, 10,33,53,71,73,75,77,85,101,201,202,999,11111]
    
    def search(find_num,seq):
        if len(seq) == 0:
            print('not exists')
            return
        mid_index=len(seq)//2
        mid_num=seq[mid_index]
        print(seq,mid_num)
        if find_num > mid_num:
            #in the right
            seq=seq[mid_index+1:]
            search(find_num,seq)
        elif find_num < mid_num:
            #in the left
            seq=seq[:mid_index]
            search(find_num,seq)
        else:
            print('find it')
    

    二、匿名函数 

    当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。

    在Python中,对匿名函数提供了有限支持。还是以map()函数为例,计算f(x)=x2时,除了定义一个f(x)的函数外,还可以直接传入匿名函数:

    通过对比可以看出,匿名函数lambda x: x * x实际上就是:

    def f(x):
        return x * x
    

    关键字lambda表示匿名函数,冒号前面的x表示函数参数。

    匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。

    用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

    f = lambda x: x * x
    f(5)
    结果25
    

    同样,也可以把匿名函数作为返回值返回,比如:

    def build(x, y):
        return lambda: x * x + y * y
    

    三、max、min、lambda  

    1.max、min、lambda 

    salaries={
    'egon':3000,
    'alex':100000000,
    'wupeiqi':10000,
    'yuanhao':2000
    }
    
    print(max(salaries.values()))
    res=zip(salaries.vaues(),salaries.key())
    print(max(res))
    结果(100000,alex)
    

      

    salaries={
    'egon':3000,
    'alex':100000000,
    'wupeiqi':10000,
    'yuanhao':2000
    }
    print(max(salaries,key=lambda k:salaries[k]))#salarier每次迭代将字典的k值赋值给k
    print(min(salaries,key=lambda k:salaries[k]))#salarier每次迭代将字典的k值赋值给k
    print(sorted(salaries,key=lambda x:salaries[x])) 每次迭代将字典的k值赋值给x,默认是最小到大
    print(sorted(salaries,key=lambda x:salaries[x],reverse=True)) #加reverse参数 True从大到小

     2.global

    #应用
    x=1000
    def f1():
        global x#如果使用关键字global那么此时使用函数内定义的x
        x=0
    
    f1()
    print(x)
    
    结果 x=0
    

    3.map应用

    l=["1",'2','3']
    res=map(lambda x:x+'sb',l)#迭代l列表并将每个元素加一个sb
    print(list(res))
    结果:
    ['1sb', '2sb', '3sb']
    
    求每个值得平方
    nums=(1,2,3,4)
    res=map(lambda x:x**2,nums)
    print(linst(res))
    

    4.reduce

    l=[1,2,3,4]
    print(reduce(lambda x,y:x+y,l))#先拿到一个初始值然后然后和后边的值累加
    
    #带初始值的
    print(reduce(lambda x,y:x+y,l,10))如果初始值是10的话那么每次结果跟10相加
    

    5.filter

    l=[1,2,3,4]
    fes=filter(lambda x:x>2,l)
    print(list(fes))
    
    
    l=("hanhan_s","li_s")
    fes=filter(lambda x:x.endswith("s"),l)
    

      

     

     

  • 相关阅读:
    objective-c内存管理中autorelease的作用
    objective-c在Xcode中@property相关参数的解释
    objective-c中的内存管理
    c#扩展方法-摘自msdn
    objective-c中的category
    c语言中结构体的定义、初始化及内存分配
    c语言中的结构体为值类型,当把一个结构体赋值给另一个结构体时,为值传递
    手动通过Lucene判断该pom文件中jar是否存在,子依赖没判断
    代码方式删除SVN
    Maven多层嵌套
  • 原文地址:https://www.cnblogs.com/hanjialong/p/6932752.html
Copyright © 2011-2022 走看看