• 闭包、迭代器、递归


    一、函数名的使用

    一、函数名的使用

    返回值 函数名 (返回函数名的时候不能加括号)

    函数名可以当容器的元素

    函数名可以当做参数被传递

    def func():
        print('func')
    def func1():
        return func  # 将函数名func作为返回值,返回给了func1()
    func1()()
    def func1():
        print('这是func1')
    def func2():
        print('这是func2')
    def func3():
        print('这是func3')
    li = [func1,func2,func3]
    for i in li:
        i()
    这是func1
    这是func2
    这是func3
    
    当容器的元素
    def func():
        print('这里打印 func')
    def test(k):
        k()
    test(func)  # 将函数名当作参数传递

    二、闭包

     一、什么是闭包

    1、首先又一个嵌套函数

    2、嵌套函数的内部函数调用非全局的变量

    3、将内部函数名当作返回值返回、在全局调用

    二、怎么查看闭包?

    1、函数名.__closure__返回None 就不是闭包

    三、闭包的特点

    1、保护变量

    2、可以让一个变量常驻内存(比如爬虫、不用每次都去重新请求网页)

    四、闭包的应用

    1、和全局变量一样,他不确定什么时间会被调用,所以会常驻内存,随时等候被调用,例如:爬虫、第一次请求就会把你想要的数据常驻内存中、方便呢以后调用;

    五、闭包函数示例

    def test():
        url = 'www.baidu.com'
        def func():
            print(url)  # 引用外部作用域的变量
        return func     # 返回func的内存地址
    res = test()
    res()   # www.baidu.com
    print(test())  # <function test.<locals>.func at 0x0000021AE401A950>
    
    def func1():
        a = 10
        def func2(num):
            nonlocal a   # 可以通过关键字进行修改
            a += num
            print(a)
        return func2
    func1()(100)
    查看是否是闭包函数,打印结果不是None就是闭包

     三、迭代器

    一、什么是迭代器

    具有__iter__方法就是可迭代对象
    
    li = [1,2,3]
    a = li.__iter__()
    
    li具有__iter__方法,所以是可迭代对象

    二、什么是迭代器

    同时具有__iter__方法和__next__方法的就是迭代器
    for循环的机制 就是迭代器;
    
    #优点:
      # - 提供一种统一的、不依赖于索引的迭代方式
      # - 惰性计算,节省内存
    #缺点:
      # - 无法获取长度(只有在next完毕才知道到底有几个值)
      # - 一次性的,只能往后走,不能往前退
    1 li = [1,2,3]
    2 a = li.__iter__()
    3 print(a.__next__())
    4 print(a.__next__())  #一个一个取
    5 print(a.__next__())
    6 print(a.__next__())  #将可迭代对象内的元素全部取完后在取会抛出'StopIteration'
    普通
     1 li = [1,2,3,4,6,7,87,8,9,90,0,0,0,0,8,7,7,67,]
     2 em = li.__iter__()
     3 while 1:
     4     try:
     5         print(em.__next__())
     6 
     7     except StopIteration:
     8         break
     9 
    10 当出现 StopIteration 直接退出循环
    11 
    12 异常捕获
    异常捕获

    四、递归

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数,记住哦->在函数内部调用其他函数不是函数的嵌套,而在函数内部定义子函数才是函数的嵌套;

    举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:

    fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

    所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。于是,fact(n)用递归的方式写出来就是

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

    如果我们计算fact(5),可以根据函数定义看到计算过程如下:

    ===> 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

    递归函数的优点

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

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

    3、自己玩自己的(自己调用自己本身)

    4、玩的有限制(有明确的结束条件)

    5、修改递归的最大层

    import sys
    sys.setrecursionlimit(10000)

    6、示例

    def fun(n):
        print(n)
        if n / 2 == 0:
            return n
        res = fun(int(n/2))
        return res
    fun(10)
  • 相关阅读:
    hdu 1296
    hdu 2101
    hdu 2100
    codeforces 3C
    codeforces 2A
    codeforces 1B
    codeforces 811B
    关于sws_scale() 段错误
    cf 1288 D. Minimax Problem (好题)(二分+二进制表状态+枚举)
    opencv4 鼠标事件 鼠标画线条
  • 原文地址:https://www.cnblogs.com/NumerOne/p/11457656.html
Copyright © 2020-2023  润新知