• Python函数


    函数

    函数
    (1)函数的含义:
    功能 (包裹一部分代码 实现某一个功能 达成某一个目的)
    (2)函数特点:
    可以反复调用,提高代码的复用性,提高开发效率,便于维护管理
    (3)函数基本格式
    # 函数的定义
    def func():
    	code1....
    	code2....
    
    # 函数的调用
    func()
    (4)函数命名
    """
    		  函数的命名
    字母数字下划线,首字符不能位数字
    严格区分大小且,且不能使用关键字
    函数命名有意义,且不能使用中文
    
    驼峰命名法:
    (1)大驼峰命名法:每个单词的首字符大写 (一般在类中起名用这样的方式, 推荐)
    	mycar => MyCar  
    (2)小驼峰命名法:除了第一个单词首字符不用大写之外,剩下首字符都大写 				(函数中的命名)
    	mycar => myCar 
    """
    函数参数 : 函数运算时需要的值
    (1)函数参数概念及分类
      函数参数:调用时需要传递的数据.
      函数参数大类分为形参和实参:
          形参意思: 函数定义时的参数
          实参意思: 函数调用时的参数
      形实关系:函数调用时,形参和实参个数需要一一对应
      形参种类: 普通参数(位置参数),默认参数,普通收集参数,命名关键字参数,关键字收集参数
      实参种类: 普通实参,关键字实参
    # 1.普通参数
    """
    函数的定义处,普通形参
    """
    def small_start(hang,lie):
        i = 0
        while i<hang:
            j = 0
            while j<lie:
                # 打印星星
                print("*",end="")
                j+=1
            # 打印换行
            print()
            i+=1
    # 函数的调用出为实参
    small_start(3,8)
    
    # 2. 默认形参 hang,lie 在函数定义处给与默认值
    """
        如果给与实参,那么就使用实际参数,
        如果没给实参,那么就使用参数的默认值
    """
    def small_start(hang=10,lie=10):
        i = 0
        while i<hang:
            j = 0
            while j<lie:
                # 打印星星
                print("*",end="")
                j+=1
            # 打印换行
            print()
            i+=1
    
    # 3. 普通形参 + 默认形参 
    """默认形参必须写在普通形参的后面,语法上有要求"""
    # 函数的定义处
    def small_start(hang,lie=10):
    # def small_start(hang,lie=10):
        i = 0
        while i<hang:
            j = 0
            while j<lie:
                # 打印星星
                print("*",end="")
                j+=1
            # 打印换行
            print()
            i+=1
    
    # (4) 关键字实参
    """
    (1)如果使用关键字实参进行函数调用,实参的顺序无所谓
    (2)如果定义时是普通形参,调用时是关键字实参,
    那么这个参数后面的所有调用方式都需要关键字实参进行调用
    """
    def small_start(hang,a,b,c,lie=10):
    # def small_start(hang,lie=10):
        i = 0
        while i<hang:
            j = 0
            while j<lie:
                # 打印星星
                print("*",end="")
                j+=1
            # 打印换行
            print()
            i+=1
    # 关键字实参 hang  和 lie 
    small_start(lie = 12,hang = 12)
    
            
    函数参数
    (2)收集参数:
    普通收集参数:专门用于收集多余的普通实参,形成一个新的元组
    语法:参数前面加* 例:*args(arguments)
    # 计算任意长度的累加和
    def my_sum(*args):
        total = 0
        for i in args:
            total += i
        print(total)
    my_sum(1,2,3,4,5)
        关键字收集参数:专门用于收集多余的关键字实参,形成一个新的字典
    语法:参数前面加** 例:**kwargs(keword arguments)
    # 拼接任意字符串
    def func(**kwargs):
        strvara = ""
        strvarb = ""
        dictvar = {"stra":"1","strb":"2"}
        for k,v in kwargs.items():
            if k in dictvar:
                strvara += dictvar[k] + ":" + v + "
    "
            else:
                strvarb += v + " "
        print(strvara)
        print(strvarb)
    
    func(stra="A",strb="B",strc="C")
    (3)命名关键字参数:定义时放在*号后面的参数,调用时强制必须指定关键字实参才能调
    语法:(*,x) x是命名关键字参数
    # 命名关键字参数
    # 方法一
    def func(a,b,*,c,d):
        print(a,b)
        print(c,d)
    func(1,2,c=3,d=4)
    # 方法二
    def func(*args,c,**kwargs):
        print(args)
        print(c)
        print(kwargs)
    func(1,2,3,4,a=1,b=2,c=3)
    # 方法三
    def func(a,b,*,c=3):
        print(a,b)
        print(c)
    func(1,2,c=33)
    # 区别于默认形参
    def func(a,b,c=3):
        print(a,b)
        print(c)
    func(1,2)
    func(1,2,c=33)
    func(1,2,33) # 关键字参数只能传关键字 
    (4)*和**的魔术用法:打包和解包 
      *和**,在函数的定义处,负责打包(把实参都收集过来,放在元组或字典中)
      *和**,在函数的调用处,负责解包(把容器类型的数据,一个一个拿出来,进行传递)
    # *
    def func(a,b,c):
        print(a,b,c)
    listvar = [1,2,3]
    func(*listvar)
    
    # **
    def func(a,*,b,c,d):
        print(a)
        print(b,c,d)
    dictvar = {"b":2,"c":3,"d":4}
    func(1,**dictvar)
    """
    在字典的前面加上一个*号,默认只传递健
    """
    def func(a,b):
        print(a,b)
    dictvar = {"a":1,"b":2}
    func(*dictvar)
    
    # *字符串
    def func(a,b):
        print(a,b)
    strvar = "12"
    func(*strvar)
    (5)形参声明的位置顺序:
    普通参数 -> 默认参数 -> 收集参数 -> 命名关键字参数 -> 关键字收集参数

    (6)对于任意函数,都可以通过 def func(*args, **kw) 来获取所有参数

    return

    return返回值
    为这个函数返回一个结果 (return返回值可有可无 按照需求选择)
    注意:执行return语句之后,函数执行结束
    """
    return 自定义返回值,如果没有写return ,默认返回None
    功能:把值返回到函数的调用处;
    (1)return 后面可以返回值 是自定义的. 除了6大标准数据类型之外,还有类 对象 函数 
    (2)如果执行了return 语句,意味着函数终止,后面的代码不执行
    """
    # (1) return 后面可以返回值 是自定义的. 除了6大标准数据类型之外,还有类 对象 函数 
    def func():
    	# return 1
    	# return 3.14
    	# return 3+4j
    	# return True
    	# return [1,2,3]
    	# return {"a":1,"b":2}
    	pass
    res = func() # res ={"a":1,"b":2}
    print(res)
    
    # (2) 如果执行了return 语句,意味着函数终止,后面的代码不执行
    def func():
        print(1)
        return 
        print(2)
    res = func()
    print(res)
    
    def func():
        for i in range(5):
            if i == 3:
                return i 
            print(i)
    res = func()
    
    
    # (3) 计算器示例
    def calc(sign, num1, num2):
        if sign == "+":
            res = num1 + num2
        elif sign == "-":
            res = num1 - num2
        elif sign == "*":
            res = num1 * num2
        elif sign == "/":
            if num2 == 0:
                return "除数不能为零"
            res = num1 / num2
        return res
    
    res = calc("+", 1, 1)
    res = calc("-", -1, 90)
    res = calc("*", 52, 10)
    res = calc("/", 52, 10)
    res = calc("/", 5200, 10)
    print(res)

    doc

    __doc__或者help查看文档
    # __doc__
    help(print)
    res = print.__doc__
    print(res)
    
    # 自定义函数文档
    def defined_word():
        """
        功能:自定义函数文档
        参数:
        :return: None
        """
        print("自定义函数文档")
    # 方法一
    res = defined_word.__doc__
    print(res)
    
    # 方法二
    help(defined_word)

    内置函数

    abs    绝对值函数
    >>> res = abs(-90.7)
    >>> res
    90.7
    >>>
    round  四舍五入 (n.5 n为偶数则舍去 n.5 n为奇数,则进一!)
    >>> print(round(2.5))
    2
    >>> print(round(3.5))
    4
    >>>
    sum    计算一个序列得和
    >>> tuplevar = (1,2,3,4,5)
    >>> print(sum(tuplevar))
    15
    >>>
    max    获取一个序列里边的最大值
    min   获取一个序列里边的最小值
    >>> listvar = [11,88,66,33,77]
    >>> print(max(listvar))
    88
    >>> print(min(listvar))
    11
    >>> listvara = sorted(listvar)
    >>> listvara
    [11, 33, 66, 77, 88]
    >>> # 最大值
    ...
    >>> print(listvara[-1])
    88
    >>> # 最小值
    ...
    >>> print(listvara[0])
    11
    >>>
    >>> # 获取一个序列里面的最小值,key=自定义函数
    ...
    >>> listvar = [("a",88),("b",66),("c",99)]
    >>> def func(n):
    ...   return n[1] % 10
    ...
    >>> res = min(listvar,key=func)
    >>> print(res)
    ('b', 66)
    >>>
    pow    计算某个数值的x次方
    >>> # 第三个参数时可选项,如果存在,前两个平方后和第三个取余
    ...
    >>> print(pow(2,3))
    8
    >>> print(pow(2,3,3))
    2
    >>>
    range  产生指定范围数据的可迭代对象
    >>> for i in range(9,0,-2):
    ...   print(i)
    ...
    9
    7
    5
    3
    1
    >>>
    bin    将10进制数据转化为二进制
    oct   将10进制数据转化为八进制
    hex   将10进制数据转化为16进制
    >>> print(bin(6))
    0b110
    >>> print(oct(9))
    0o11
    >>> print(hex(16))
    0x10
    >>>
    chr    将ASCII编码转换为字符
    ord   将字符转换为ASCII编码
    >>> print(chr(97))
    a
    >>> print(ord("A"))
    65
    >>>
    eval   将字符串当作python代码执行
    exec   将字符串当作python代码执行(功能更强大)
    >>> strvar = "print(123)"
    >>> res = eval(strvar)
    123
    >>> print(res) # 返回值没有意义
    None
    >>>
    >>> strvar = 'course = "python"'
    >>> res = eval(strvar) # 声明变量,eval不允许
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1
        course = "python"
               ^
    SyntaxError: invalid syntax
    >>>
    >>> strvar = 'course = "python"'
    >>> res = exec(strvar)
    >>> print(course)
    python
    >>> print(res)
    None
    >>>
    >>> strvar = """
    ... for i in range(5):
    ...   print(i)
    ... """
    >>> exec(strvar)
    0
    1
    2
    3
    4
    >>>
    repr   不转义字符输出字符串
    >>> strvar = "D:
    ote"
    >>> print(strvar)
    D:
    ote
    >>> print(repr(strvar))
    'D:
    ote'
    >>>
    input  接受输入字符串
    >>> res = input("Please input username>>>")
    Please input username>>>admin
    >>>
    hash   生成哈希值
    >>> strvara = "password"
    >>> strvarb = "password"
    >>> print(hash(strvara))
    -8671913786014747281
    >>> print(hash(strvarb))
    -8671913786014747281
    >>>

    参数练习

    def f1(a, b, c=0, *args, **kw):
      print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

    def f2(a, b, c=0, *, d, **kw):
      print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

    以上两个函数 打印结果
    #(一)
    f1(1, 2)
    f1(1, 2, c=3)
    f1(1, 2, 3, 'a', 'b')
    f1(1, 2, 3, 'a', 'b', x=99)
    f2(1, 2, d=99, ext=None)
    #(二)
    args = (1, 2, 3, 4)
    kw = {'d': 99, 'x': '#'}
    f1(*args, **kw)

    #(三)
    myargs = (1, 2, 3)
    mykw = {'d': 88, 'x': '#'}
    f2(*myargs, **mykw)

    #(四)
    def f1(a, b, c=0, *args,d,**kw):
      print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
      print(d)

    f1(1,2,3, 'a', 'b',d=67, x=99,y=77)
    >>> def f1(a,b,c=0,*args,**kw):
    ...   print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)
    ...
    >>> def f2(a,b,c=0,*,d,**kw):
    ...   print('a=',a,'b=',b,'c=',c,'d=',d,'kw=',kw)
    ...
    >>> f1(1,2,c=3)
    a= 1 b= 2 c= 3 args= () kw= {}
    >>> f1(1,2,3,'a','b')
    a= 1 b= 2 c= 3 args= ('a', 'b') kw= {}
    >>> f1(1,2,3,'a','b',x=99)
    a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'x': 99}
    >>> f2(1,2,d=99,ext=None)
    a= 1 b= 2 c= 0 d= 99 kw= {'ext': None}
    >>> args=(1,2,3,4)
    >>> kw={'d':99,'x':'#'}
    >>> f1(*args,**kw)
    a= 1 b= 2 c= 3 args= (4,) kw= {'d': 99, 'x': '#'}
    >>> myargs=(1,2,3)
    >>> mykw={'d':88,'x':'#'}
    >>> f2(*myargs,**mykw)
    a= 1 b= 2 c= 3 d= 88 kw= {'x': '#'}
    >>> def f1(a,b,c=0,*args,d,**kw):
    ...   print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)
    ...   print(d)
    ...
    >>> f1(1,2,3,'a','b',d=67,x=99,y=77)
    a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'x': 99, 'y': 77}
    67

    函数名的使用

    python中的函数可以像变量一样,动态创建,销毁,当参数传递,作为值返回,叫第一类对象.其他语言功能有限
    1.函数名是个特殊的变量,可以当做变量赋值
    2.函数名可以作为容器类型数据的元素
    3.函数名可以作为函数的参数
    4.函数名可作为函数的返回值
    >>> # 1.函数名是个特殊的变量,可以当做变量赋值
    ... def func():
    ...     print("函数名可以当成变量赋值")
    ...
    >>> abc = 45
    >>> abc = func
    >>> print(abc)
    <function func at 0x00000209F87256A8>
    >>> abc()
    函数名可以当成变量赋值
    >>>
    >>># 2.函数名可以作为容器类型数据的元素
    >>> def func1():
    ...   print(1)
    ...
    >>> def func2():
    ...   print(2)
    ...
    >>> listvar = [func1,func2]
    >>> print(listvar)
    [<function func1 at 0x00000209F87257B8>, <function func2 at 0x00000209F8725730>]
    >>> for i in listvar:
    ...   i()
    ...
    1
    2
    >>>
    >>> # 3.函数名可以作为函数的参数
    ...
    >>> def func1(func):
    ...   func()
    ...
    >>> def func2():
    ...   print('func2')
    ...
    >>> func1(func2)
    func2
    >>>
    >>> # 4.函数名可以作为函数的返回值
    ...
    >>> def func1(func):
    ...   return func
    ...
    >>> def func2():
    ...   print('func2')
    ...
    >>> res = func1(func2)
    >>> print(res)
    <function func2 at 0x00000209F8725840>
    >>> res()
    func2
    >>>
    __doc__或者help查看文档

    命名空间

    作用域:作用范围
    命名空间 : 划分一块区域保存所有数据,以字典的方式存储(变量与值形成映射关系).一共三种.
    (1)内建命名空间:解释器启动时创建,直到解释器运行结束,生存周期最长
    (2)全局命名空间:文件运行时创建,直到解释器运行结束,生存周期较长
    (3)局部命名空间:函数调用时,里面的局部变量才创建,调用结束后即释放,生存周期较短
    命名空间的提出是为了划分和控制变量是否可见,以及生存周期的长短.

    命名空间 创建顺序:(了解)
    python解释器启动->创建内建命名空间->创建全局命名空间->创建局部命名空间
    命名空间 销毁顺序:(了解)
    函数调用结束后->销毁函数对应的局部命名空间数据->销毁全局命名空间数据->销毁内建命名空间数据

    全局变量 与 局部变量 及 其关键字的使用

    局部变量:函数内部的变量是局部变量,作用域仅在函数内部可见(局部命名空间)
    全局变量:函数外部的变量是全局变量,作用域横跨整个文件(全局命名空间)
    # 局部变量的获取 与 修改
    def func():
    	a = 15
    	# 获取局部变量
    	print(a)
    	# 修改局部变量
    	a = 17
    	print(a)
    func()
    # print(a) error  a局部变量值限定在函数内部使用;
    
    # 全局变量的获取 与 修改
    b = 100
    # 获取全局变量
    print(b)
    # 修改全局变量
    b += 200
    print(b)
    内置函数:内建命名空间

    global   :关键字:声明全局变量获修改全局变量
    # 在函数内部可以直接获取全局变量,但是不能直接修改
    # 用global关键字,修改全局变量
    c = 50
    def func():
    	global c
    	print(c)
    	c = 60
    	print(c)
    func()
    print(c)
    
    
    # 在函数内部可以直接定义一个全局变量
    def func():
    	global d
    	d = 90
    func()
    print(d)
    nonlocal  :关键字:修改局部变量(当前函数上一层的局部变量)
    # (1) nonlocal 只能用来修改局部变量
    a = 90
    def func():
    	# nonlocal a  error
    	a = 80
    	print(a)
    func()
    
    # (2) nonlocal 会不停的寻找上一层空间所对应的值,拿来修改
    """通过LEGB原则,可以获取到上一层空间的值,只能单纯的获取,不能直接修改
    如果想要修改 通过nonlocal 加以修饰.
    """
    def outer():
    	a = 20
    	def inner():
    		nonlocal a
    		print(a)
    		a += 1
    		print(a)
    	inner()
    outer()
    
    # (3) 如果上一层找不到,继续向上寻找,再也找不到了,直接报错; nonlocal 只能修饰局部变量
    a = 100
    
    def outer():
    	a = 100
    	def inner():
    		# a = 110
    		def smaller():
    			nonlocal a
    			a += 10
    			# print(a)
    		smaller()
    		print(a,"<=1=>")
    	inner()
    	print(a,"<=2=>")
    outer()
    
    
    # (4) 不通过nonlocal 是否可以改变局部变量? 可以! 需要使用列表进行操作;
    def outer():
    	lst = [100,101,102]
    	def inner():
    		lst[0] += 1
    	inner()
    	print(lst)
    outer()
    locals()  :返回字典,获取当前作用域的所有内容
      如果在函数里:获取locals()调用之前,该作用域出现的内容
      如果在函数外:获取locals()打印返回值之前,该作用域出现的内容
    # 当前作用域在全局范围
    a = 1
    b = 2
    res = locals()
    c = 3
    print(res)
    # 当前作用域在局部范围
    zz = 90
    def func():
    	d = 4
    	f = 5
    	res = locals()
    	g = 6
    	print(res)
    
    func()
    globals() :返回字典,获取全局作用域的所有内容
      如果在函数里: 获取globals()调用之前,全局作用域出现的内容
      如果在函数外: 获取globals()打印返回值之前,全局作用域出现的内容
    """
    globals 无论在函数内外,都只获取全局作用域当中的所有内容
    如果globals在函数外:所获取的是globals(),打印返回值之前的所有内容
    如果globals在函数内:所获取的是globals(),调用之前所有内容
    """
    # 当前作用域在全局范围
    a = 1
    b = 2
    res = globals()
    c  = 3
    print(res)
    
    # 当前作用域在局部范围
    aa = 11
    bb = 22
    def func():
        d =1
        f = 2
        res = globals()
        z = 3
        print(res)
    cc = 33
    func() #res = globals()
    dd = 4
    
    # globals 动态的创建全局变量
    """
    globals() 返回的是系统的字典,只需要在字典里面添加键值对,就可以创建全局变量
    字典中的键 就是变量名
    字典中的值 就是变量所指代的值
    """
    dic = globals()
    print(dic)
    dic["strvar"] = "abc"
    print(strvar)
    
    # 创建p1~p5 5个全局变量
    def func():
        dic = globals()
        for i in range(1,6):
            # p1 ~ p5 5个键
            dic["p%d" % (i)] = i
    func()
    print(p1)
    print(p2)
    print(p3)
    print(p4)
    print(p5)
    globals 

    LEGB原则(即就近原则找变量)

    找寻变量的调用顺序采用LEGB原则(即就近原则)
    B —— Builtin(Python);Python内置模块的命名空间     (内建作用域)
    G —— Global(module); 函数外部所在的命名空间       (全局作用域)
    E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
    L —— Local(function);当前函数内的作用域           (局部作用域)
    依据就近原则,从下往上 从里向外 依次寻找

    内部函数

    (1)内部函数可以直接在函数外部调用么
    (2)调用外部函数后,内部函数可以在函数外部调用吗
    (3)内部函数可以在函数内部调用吗
    (4)内部函数在函数内部调用时,是否有先后顺序
    >>> # 函数的嵌套
    ...
    >>> def outer():
    ...   def inner():
    ...     def smaller():
    ...       print(id)
    ...       print('small func')
    ...     smaller()
    ...   inner()
    ...
    >>> outer()
    <built-in function id>
    small func
    >>>

    闭包

    获取闭包函数使用的变量  __closure__ , cell_contents

    闭包的定义:
    内函数使用外函数的局部变量,并且外函数将内函数返回出来的方法叫闭包,
    返回的内函数叫 闭包函数.

    闭包的特点:
      内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长该变量的生命周期
      (实际内存给它存储了这个值,暂时不释放)
    """
    内函数使用了外函数的局部变量,外函数的局部变量与内函数发生绑定,延长了该变量的生命周期
    """
    def outer(val):
    	def inner(num):
    		return num +  val
    	return inner
    
    func = outer(10)
    res = func(5) # func = inner() = num + val = 10 + 5 = 15
    print(res)

    闭包的意义:
    闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
    """
    闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
    模拟一个鼠标点击计数功能:
    """
    clicknum = 0
    def clickfunc():
    	global clicknum
    	clicknum += 1
    	print(clicknum)
    
    # 模拟点击操作,点击一次就调用一次
    clickfunc()
    clickfunc()
    clickfunc()
    clickfunc()
    clickfunc()
    clicknum = 100
    clickfunc()
    
    # 用闭包函数来进行改造
    def clickfunc():
    	x = 0
    	def func():
    		nonlocal x
    		x +=1 
    		print(x)
    	return func
    clickfunc2 = clickfunc()
    clickfunc2() # clickfunc2() = func()
    clickfunc2() 
    clickfunc2() 
    clickfunc2() 
    clickfunc2() 
    x = 100
    clickfunc2() 
    

    匿名函数

    lambda 表达式:用一句话来表达只有返回值的函数
       好处:简洁,方便,定义函数快速简单
       语法:lambda 参数 : 返回值
    >>> # 1.无参数的lambda表达式
    ...
    >>> def func():
    ...   return 123
    ...
    >>> res = func()
    >>> print(res)
    123
    >>> func = lambda:123
    >>> res = func()
    >>> print(res)
    123
    >>>
    >>> # 2.有参数的lambda表达式
    ...
    >>> def  func(n):
    ...   return type(n)
    ...
    >>> res = func('123')
    >>> print(res)
    <class 'str'>
    >>> func = lambda n : type(n)
    >>> res = func('123')
    >>> print(res)
    <class 'str'>
    >>>
    >>> # 3.带有条件判断的lambda表达式
    """
    三元运算:
      真值 if 条件表达式 else 假值
    	如果条件表达式成立,执行真值
    	如果条件表达式不成立,执行假值
    """
    >>> def func(n):
    ...   if n % 2 == 0:
    ...     return "偶数"
    ...   else:
    ...     return "奇数"
    ...
    >>> func(11)
    >>> n = 11
    >>> func = "偶数" if n % 2 == 0 else "奇数"
    >>> func
    '奇数'
    >>>
    >>> # 计算参数中的最大值
    ...
    >>> def func(m,n):
    ...   if m > n:
    ...     return m
    ...   else:
    ...     return n
    ...
    >>> print(func(11,33))
    33
    >>> func = lambda m,n : m if m > n else n
    >>> print(func(11,33))
    33
    >>>
    

    递归函数

    递归函数:自己调用自己的函数 (递:去 归:回 一去一回是递归)
      (1)每调用一次函数,就是开辟一个栈帧空间的过程
    每结束一次函数,就是释放一个栈帧空间的过程
    递归函数就是不停的开辟栈帧空间和释放栈帧空间的过程

    (2)回的过程有两种触发时机:
    (1)当最后一层函数全部执行完毕,触发回的过程,回到上一层函数调用处
    (2)当遇到return 返回值的时候,触发回的过程,回到上一层函数调用处
    >>> def recursion(n):
    ...   print("session01>>>",n)
    ...   if n > 0:
    ...     recursion(n-1)
    ...   print("session02>>>",n)
    ...
    >>> recursion(5)
    session01>>> 5
    session01>>> 4
    session01>>> 3
    session01>>> 2
    session01>>> 1
    session01>>> 0
    session02>>> 0
    session02>>> 1
    session02>>> 2
    session02>>> 3
    session02>>> 4
    session02>>> 5
    >>>
    >>> # 计算n的阶乘
    ...
    >>> def factorial(n):
    ...   if n <= 1:
    ...     return 1
    ...   return n * factorial(n-1)
    ...
    >>> res = factorial(5)
    >>> print(res)
    120
    >>> 

    如果我们计算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

    内存栈区堆区(了解内容)

    单独讲栈堆是数据结构
      栈:后进先出的一种数据结构
      堆:排序后的一种树状数据结构
       
    栈区堆区是内存空间
      栈区:按照后进先出的数据结构(栈),无论创建或销毁都是自动为数据分配内存,释放内存
    (系统自动做的)
      堆区:按照排序后的树状数据结构(堆),可优先取出必要数据,无论创建或销毁都是手动分配内存,释放内存(程序员手动做的)
      --内存中的栈区 : 自动分配 自动释放
      --内存中的堆区 : 手动分配 手动释放

    运行程序时在内存中执行,会因为数据类型的不同而在内存的不同区域运行
    因不同语言对内存划分的机制不一,但大体来讲,有如下四大区域

    --栈区: 分配局部变量空间.
    --堆区: 是用于手动分配程序员申请的内存空间.
    --静态区(全局栈区): 分配静态变量,全局变量空间.
    --代码区(只读区,常量区): 分配常量和程序代码空间的.

    栈区 堆区 静态区 代码区 都是内存中的一段空间

    迭代器

    迭代器:能被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator  迭代器是对象)
    特征:迭代器会生成惰性序列,它通过计算把值依次的返回,一边循环一边计算而不是一次性得到所有数据
    优点:需要数据的时候,一次取一个,可以大大节省内存空间.而不是一股脑的把所有数据放进内存.

    --Iterable可迭代的 Iterator迭代器
    惰性序列:没有一次性的把所有数据都放在序列中,而是遍历一个放一个,这样的序列

    1.可迭代对象。

      如果一个数据类型其中的成员包含了__iter__方法,这个数据类型就是可迭代对象

      dir 这个函数可以获取该数据类型的成员结构

    >>> setvar ={1,2,'a','b'}
    >>> setvar
    {1, 2, 'b', 'a'}
    >>> for i in setvar:
    ...   print(i)
    ...
    1
    2
    b
    a
    >>> res = dir(setvar)
    >>> res
    ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
    >>>
    2.迭代器
      for循环在迭代数据的时候,内部先转化为迭代器,然后通过next方法来进行调用
      变成迭代器:
        (1)iter (2)__iter__()
    >>> setvar ={1,2,'a','b'}
    >>> res = iter(setvar)
    >>> res
    <set_iterator object at 0x00000135A70DB8B8>
    >>> ret = setvar.__iter__()
    >>> ret
    <set_iterator object at 0x00000135A70DB900>
    >>>
      遍历迭代器
        (1)next (2)__next__()
    >>> setvar ={1,2,'a','b'}
    >>> res = iter(setvar)
    >>> ret = next(res)
    >>> ret
    1
    >>> ret = next(res)
    >>> ret
    2
    >>> ret = next(res)
    >>> ret
    'b'
    判断可迭代对象
    >>> setvar ={1,2,'a','b'}
    >>> res = iter(setvar)
    >>> print("__iter__" in dir(setvar))
    True
    >>> 
    判断迭代器
        (1)含有__iter__和__next__两个方法,该数据类型就是迭代器
    >>> setvar ={1,2,'a','b'}
    >>> res = iter(setvar)
    >>> print("__iter__" in dir(res) and "__next__" in dir(res))
    True
    >>>
        (2)from collections import Iterator,Iterable 
    >>> from collections import Iterator,Iterable
    >>> listvar = [1,2,3,4]
    >>> # 是否是一个迭代器
    ...
    >>> res = isinstance(listvar,Iterator)
    >>> res
    False
    >>> # 是否是可迭代对象
    ...
    >>> res = isinstance(listvar,Iterable)
    >>> res
    True
    >>>
      迭代器是可迭代对象
      可迭代对象不一定是迭代器

    range 是 可迭代对象
    >>> res = isinstance(range(10),Iterator)
    >>> res
    False
    >>> res = isinstance(range(10),Iterable)
    >>> res
    True
    >>>
    range 和 迭代器 能够产生惰性序列 
    在调用时,超出了原有的数据个数,会直接越界报错
    >>> it = iter(range(3))
    >>> print(next(it))
    0
    >>> print(next(it))
    1
    >>> print(next(it))
    2
    >>> print(next(it))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
    

      遍历

      通过for和next配合使用

    >>> it = iter(range(5))
    >>> for i in range(3):
    ...   res = next(it)
    ...   print(res)
    ...
    0
    1
    2
    >>>
    

      通过for一次性遍历迭代器中所有数据

    >>> it = iter(range(5))
    >>> for i in it:
    ...   print(i)
    ...
    0
    1
    2
    3
    4
    >>>

    高阶函数

    高阶函数:能够把函数当成参数传递的就是高阶函数

    map
    map(func,iterable)
    功能:
    把iterable里面所有数据 一一的放进到func这个函数中进行操作 ,把结果扔进迭代器
    参数:
    func 内置或自定义函数
    iterable 具有可迭代性的数据 ([迭代器],[容器类型的数据],[range对象])
    返回值:
    返回最后的迭代器
    例1:["1","2","3","4"] ==> [1,2,3,4]
    常规方法
    >>> listvar = ["1","2","3","4"]
    >>> listvara = []
    >>> for i in listvar:
    ...   res = int(i)
    ...   listvara.append(res)
    ...
    >>> listvara
    [1, 2, 3, 4]
    >>>
    

      使用map

    >>> listvar = ["1","2","3","4"]
    >>> from collections import Iterator,Iterable
    >>> it = map(int,listvar)
    >>> print(isinstance(it,Iterator))
    True
    >>> print(next(it))
    1
    >>> print(next(it))
    2
    >>> print(next(it))
    3
    >>> print(next(it))
    4
    >>> # 使用for进行调用
    ...
    >>> it = map(int,listvar)
    >>> for i in it:
    ...   print(i)
    ...
    1
    2
    3
    4
    >>> # for配合next进行调用
    ...
    >>> it = map(int,listvar)
    >>> for i in range(2):
    ...   res = next(it)
    ...   print(res)
    ...
    1
    2
    >>> # 使用list强转成列表
    ...
    >>> it = map(int,listvar)
    >>> lst = list(it)
    >>> lst
    [1, 2, 3, 4]
    >>>
    

      例2:[1,2,3,4] ==> [3,6,9,12]

    >>> listvar = [1,2,3,4]
    >>> listvara = []
    >>> for i in listvar:
    ...   res = i * 3
    ...   listvara.append(res)
    ...
    >>> listvara
    [3, 6, 9, 12]
    >>>
    

      map

    >>> listvar = [1,2,3,4]
    >>> def func(n):
    ...   return n * 3
    ...
    >>> it = map(func,listvar)
    >>> print(list(it))
    [3, 6, 9, 12]
    >>>
    

      例3:{97:"a",98:"b",99:"c"} ==> {"a":97,"b":98,"c":99}

    >>> dictvar = {97:"a",98:"b",99:"c"}
    >>> dictvara = {}
    >>> res = dictvar.items()
    >>> res
    dict_items([(97, 'a'), (98, 'b'), (99, 'c')])
    >>> # 反转字典中的键值对
    ...
    >>> for k,v in res:
    ...   dictvara[v] = k
    ...
    >>> dictvara
    {'a': 97, 'b': 98, 'c': 99}
    >>>
    

      map自定义函数,需要一个参数,必须写一个返回值

    >>> def func(n):
    ...   dictvar = {97:"a",98:"b",99:"c"}
    ...   for k,v in dictvar.items():
    ...     dictvara[v] = k
    ...   return dictvara[n]
    ...
    >>> it = map(func,["a","b","c"])
    >>> print(list(it))
    [97, 98, 99]
    >>>
    reduce
    reduce(func,iterable)
    功能:  
      先把iterable里面的前2个数据拿到func函数当中进行运算,得到结果,
      在把计算的结果和iterable中的第三个数据拿到func里面进行运算,
      依次类推 ,直到iterable里面的所有数据都拿完为止,程序结束
    参数:
    func     内置或自定义函数
    iterable 具有可迭代性的数据 ([迭代器],[容器类型的数据],[range对象])
    返回值:
    计算的最后结果
    例1:[5,4,8,8] ==> 5488
    >>> listvar = [5,4,8,8]
    >>> strvar = ''
    >>> for i in listvar:
    ...   strvar += str(i)
    ...
    >>> print(strvar,type(strvar),int(strvar))
    5488 <class 'str'> 5488
    >>>
    

      方法二:

      5 * 10 + 4 = 54

      54 * 10 + 8 = 548

      548 * 10 + 8 = 5488 

    >>> listvar = [5,4,8,8]
    >>> it = iter(listvar)
    >>> res1 = next(it)
    >>> res2 = next(it)
    >>> res = res1 * 10 + res2
    >>> res
    54
    >>> for i in it:
    ...   res = res * 10 + i
    ...
    >>> print(res,type(res))
    5488 <class 'int'>
    >>>
    

      使用reduce进行改写

    >>> from functools import reduce
    >>> listvar = [5,4,8,8]
    >>> def func(x,y):
    ...   return x*10 + y
    ...
    >>> res = reduce(func,listvar)
    >>> print(res,type(res))
    5488 <class 'int'>
    >>>
    

      例2:"789" ==> 789 不适用int强转的前提下完成

    >>> strvar = "789"
    >>> def func(n):
    ...   dictvar = {"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}
    ...   return dictvar[n]
    ...
    >>> def funca(x,y):
    ...   return x*10 + y
    ...
    >>> it = map(func,strvar)
    >>> res = reduce(funca,it)
    >>> print(res,type(res))
    789 <class 'int'>
    >>>
    sorted 
    sorted(iterable,reverse=False,key=函数)
    功能:  
    对数据进行排序
    参数:
      iterable : 具有可迭代性的数据(迭代器,容器类型数据,可迭代对象)
      reverse   : 是否反转 默认为False 代表正序, 改成True 为倒序
      key       : 指定函数 内置或自定义函数
    返回值:
    返回排序后的数据
    >>> # 默认从小到大排序
    ...
    >>> listvar = [88,31,-90,0]
    >>> res = sorted(listvar)
    >>> res
    [-90, 0, 31, 88]
    >>> # 从大到小排序
    ...
    >>> listvar = [88,31,-90,0]
    >>> res = sorted(listvar,reverse=True)
    >>> res
    [88, 31, 0, -90]
    >>>
    

      列1:按照绝对值排序,使用内置函数

    >>> listvar = [-99,-2,45,1]
    >>> res = sorted(listvar,key=abs)
    >>> res
    [1, -2, 45, -99]
    >>>
    

      例2:按照余数排序,使用自定义函数

    >>> def func(n):
    ...   return n % 10
    ...
    >>> listvar = (19,24,91,36)
    >>> res = sorted(listvar,key=func)
    >>> res
    [91, 24, 36, 19]
    >>> listvar
    (19, 24, 91, 36)
    >>>
    filter
    filter(func,iterable)
    功能:
      用来过滤的,如果func函数中返回True , 会将这个值保留到迭代器中
      如果func函数中返回False , 会将此值舍弃不保留
    参数:
      func : 自定义函数
      iterable : 具有可迭代性的数据(迭代器,容器类型数据,可迭代对象)
    返回值:
    返回处理后的迭代器
    例1:保留偶数
    基本写法
    >>> listvar = [1,2,3,4,5,6,7,8,9]
    >>> for i in listvar:
    ...   if i % 2 ==0:
    ...     print(i)
    ...   else:
    ...     pass
    ...
    2
    4
    6
    8
    >>>
    

      filter写法

    >>> def func(n):
    ...   if n % 2 == 0:
    ...     return True
    ...   else:
    ...     return False
    ...
    >>> it = filter(func,listvar)
    >>> print(list(it))
    [2, 4, 6, 8]
    >>>
    

      简洁写法

    >>> func = lambda n:True if n % 2 == 0 else False
    >>> it = filter(lambda n : True if n % 2 == 0 else False,listvar)
    >>> print(list(it))
    [2, 4, 6, 8]
    >>>

    推导式(comprehensions)

    通过一行循环判断,遍历出一系列数据的方式是推导式
    语法: val for val in Iterable (把想要的值写在 for的左侧)
    里面是一行循环判断!根据套在推导式外层的符号判断具体是什么类型的推导式

    推导式种类三种:
      [val for val in Iterable] 列表推导式
      {val for val in Iterable} 集合推导式
      {a:b for a,b in iterable} 字典推导式
    例1:生成一个列表 listvar=[1,2,3,4,5,6,7,8,9,10]
    >>> listvar = []
    >>> for i in range(1,11):
    ...   listvar.append(i)
    ...
    >>> listvar
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>>
    

      普通列表推导式

    >>> listvar = [i for i in range(1,11)]
    >>> listvar
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    >>> listvar = [i*2 for i in range(1,11)]
    >>> listvar
    [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
    >>>
    

      带有判断条件的列表推导式

      基本写法

    >>> listvar = [1,2,3,4,5,6,7,8,9]
    >>> listvara = []
    >>> for i in listvar:
    ...   if i % 2 == 1:
    ...     listvara.append(i)
    ...
    >>> listvara
    [1, 3, 5, 7, 9]
    >>>
    

      推导式写法

    >>> listvar = [1,2,3,4,5,6,7,8,9]
    >>> listvara = [i for i in listvar if i % 2 == 1]
    >>> listvara
    [1, 3, 5, 7, 9]
    >>>
    

      双循环列表推导式

    >>> listvara = ["1","2","3"]
    >>> listvarb = ["a","b","c"]
    >>> listvar = []
    >>> for i in listvara:
    ...   for j in listvarb:
    ...     strvar = i + ":" + j
    ...     listvar.append(strvar)
    ...
    >>> listvar
    ['1:a', '1:b', '1:c', '2:a', '2:b', '2:c', '3:a', '3:b', '3:c']
    >>>
    >>> listvar = [i + ":" + j for i in listvara for j in listvarb]
    >>> listvar
    ['1:a', '1:b', '1:c', '2:a', '2:b', '2:c', '3:a', '3:b', '3:c']
    >>>
    

      带有条件判断的双循环列表推导式

    >>> listvara = ["1","2","3"]
    >>> listvarb = ["a","b","c"]
    >>> listvar = []
    >>> for i in listvara:
    ...   for j in listvarb:
    ...     if listvara.index(i) == listvarb.index(j):
    ...       strvar = i + ":" + j
    ...       listvar.append(strvar)
    ...
    >>> listvar
    ['1:a', '2:b', '3:c']
    >>>
    >>>
    >>> listvar = [i + ":" + j for i in listvara for j in listvarb if listvara.index(i) == listvarb.index(j)]
    >>> listvar
    ['1:a', '2:b', '3:c']
    >>>

    列表推导式,集合推导式,字典推导式的相关写法

    (1)普通推导式
    (2)带有判断条件的推到式
    (3)多循环推到式
    (4)带有判断条件的多循环推到式
    集合推导式(去重)
    >>> setvar = {15 if i % 2 == 1 else 16 for i in range(3)}
    >>> setvar
    {16, 15}
     (1)enumerate
    enumerate(iterable,[start=0])
    功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
    参数:
      iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
      start: 可以选择开始的索引号(默认从0开始索引)
    返回值:迭代器
    >>> from collections import Iterator,Iterable
    >>> listvar = [1,2,3,4]
    >>> it = enumerate(listvar)
    >>> print(it)
    <enumerate object at 0x000001D7FC53BAB0>
    >>> print(isinstance(it,Iterator))
    True
    >>> print(list(it))
    [(0, 1), (1, 2), (2, 3), (3, 4)]
    >>>
    

      强制迭代器变成字典

    >>> listvar = ["a","b","c"]
    >>> it = enumerate(listvar)
    >>> res = dict(it)
    >>> print(res)
    {0: 'a', 1: 'b', 2: 'c'}
    >>>
    

      字典推导式变成字典

    >>> listvar = ["a","b","c"]
    >>> it = enumerate(listvar)
    >>> dictvar = {k:v for k,v in it}
    >>> print(dictvar)
    {0: 'a', 1: 'b', 2: 'c'}
    >>>
    >>> it = enumerate(listvar,start=10)
    >>> dictvar = {k:v for k,v in it}
    >>> print(dictvar)
    {10: 'a', 11: 'b', 12: 'c'}
    >>>
     (2)zip
    zip(iterable, ... ...)
      功能: 将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中
      iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range)
    返回: 迭代器
    >>> listvara = ["1","2","3"]
    >>> listvarb = ["a","b","c"]
    >>> listvarc = ["e","f","g"]
    >>> it = zip(listvara,listvarb,listvarc)
    >>> print(list(it))
    [('1', 'a', 'e'), ('2', 'b', 'f'), ('3', 'c', 'g')]
    >>>
    

      dict强转迭代器变成字典

    >>> listvara = ["1","2","3"]
    >>> listvarb = ["a","b","c"]
    >>> res = dict(zip(listvara,listvarb))
    >>> print(res)
    {'1': 'a', '2': 'b', '3': 'c'}
    >>>
    

      字典推导式

    >>> dictvar = {k:v for k,v in zip(listvara,listvarb)}
    >>> print(dictvar)
    {'1': 'a', '2': 'b', '3': 'c'}
    >>>

    元组推导式是生成器(generator)

    元组推导式的返回值是一个生成器对象,简称生成器,生成器本质就是迭代器.

    迭代器和生成器区别:
    迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑

    生成器可以用两种方式创建:
      (1)生成器表达式 (里面是推导式,外面用圆括号)
      (2)生成器函数   (用def定义,里面含有yield)
     yield 类似于 return
    共同点在于:执行到这句话都会把值返回出去
    不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
      而return直接终止函数,每次重头调用.
    yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用

    基本定义,返回生成器对象,简称生成器
    >>> from collections import Iterator
    >>> generator_obj = (i for i in range(10))
    >>> print(generator_obj)
    <generator object <genexpr> at 0x000001D7FC506570>
    >>> print(isinstance(generator_obj,Iterator))
    True
    >>>
    

      使用next方法调用

    >>> res = next(generator_obj)
    >>> res
    0
    >>>
    

      for配合next调用

    >>> for i in range(5):
    ...   res = next(generator_obj)
    ...   print(res)
    ...
    1
    2
    3
    4
    5
    

      for循环遍历生成器

    >>> for i in generator_obj:
    ...   print(i)
    ...
    6
    7
    8
    9
    >>>

    生成器函数

    1.基本语法

    >>> def mygen():
    ...   print(1)
    ...   yield 1
    ...   print(2)
    ...   yield 2
    ...   print(3)
    ...   yield 3
    ...
    >>>
    

      初始化生成器函数,返回生成器对象,调用完后会报错

    >>> gen = mygen()
    >>> res = next(gen)
    1
    >>> res = next(gen)
    2
    >>> res = next(gen)
    3
    >>> res = next(gen)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
    

      例1:

    def mygen():
    	for i  in  range(100):
    		yield "num:{:d}".format(i)
    
    # 初始化生成器函数 ,返回生成器对象,简称生成器
    gen = mygen()
    for i in range(50):
    	res = next(gen)
    	print(res)
    
    for i in range(30):
    	print(next(gen))
    

      数据量大使用for进行遍历,会死循环

    生成器send 与 yield from

     send
    next和send区别:
    next 只能取值
    send 不但能取值,还能发送值
    send注意点:
    第一个 send 不能给 yield 传值 默认只能写None
    最后一个yield 接受不到send的发送值
    >>> def mygen():
    ...   print(1)
    ...   res1 = yield 1
    ...   print(res1,"接受返回1")
    ...   res2 = yield 2
    ...   print(res2,"接受返回2")
    ...
    >>> # 初始化生成器函数
    ...
    >>> gen = mygen()
    >>> # 第一次无法给上一个yield发送数据,强制发送None
    ...
    >>> res = gen.send(None)
    1
    >>> res = gen.send(111)
    111 接受返回1
    >>> res = gen.send(222)
    222 接受返回2
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
     yield from : 将一个可迭代对象变成一个迭代器返回
    >>> def mygen():
    ...   yield from [1,2,3]
    ...
    >>> gen = mygen()
    >>> res = next(gen)
    >>> res
    1
    >>> res = next(gen)
    >>> res
    2
    >>> res = next(gen)
    >>> res
    3
    >>>
    

      斐波那契数列(用前两数相加得到第三个)

    >>> def mygen(n):
    ...   a,b = 0,1
    ...   i = 0
    ...   while i < n:
    ...     yield b
    ...     a,b = b,a+b
    ...     i += 1
    ...
    >>> gen = mygen(5)
    >>> for i in gen:
    ...   print(i)
    ...
    1
    1
    2
    3
    5
    >>>

    练习题:

    (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式
    (2).把列表中所有字符变成小写 ["ADDD","dddDD","DDaa","sss"]
    (3).x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中
    (4).使用列表推导式 制作所有99乘法表中的运算
    (5)#求M,N中矩阵和元素的乘积
    M = [ [1,2,3], 
         [4,5,6], 
         [7,8,9] ] 

    N = [ [2,2,2], 
         [3,3,3], 
         [4,4,4] ] 
    =>实现效果1   [2, 4, 6, 12, 15, 18, 28, 32, 36]
    =>实现效果2   [[2, 4, 6], [12, 15, 18], [28, 32, 36]]




     
  • 相关阅读:
    Pytorch使用tensorboardX实现loss曲线可视化。超详细!!!
    numpy安装失败:numpy和cv2的版本不一样吧 pip安装/卸载
    问题解决:RuntimeError: CUDA out of memory.(....; 5.83 GiB reserved in total by PyTorch)
    前端刷题网站
    vscode如何使用ssh连接远程linux
    marginnote使用
    前端知识点
    HTTP状态码
    内置对象总结
    微信小程序
  • 原文地址:https://www.cnblogs.com/wangzihong/p/11183313.html
Copyright © 2020-2023  润新知