zoukankan      html  css  js  c++  java
  • 7.内置函数、作用域、闭包、递归

    1.常见的内置函数

    常见的内置函数:
    查看内置函数:
    print(dir(__builtins__))
    常见函数

    type 查看对象类型
    len 求长度
    min 求最小值
    max 求最大值
    sorted 排序
    reversed 反向
    sum 求和

    print  打印

    help 帮助

    id 查看对象内存地址

    range 从起始值到结束值按照一定步长的序列

    进制转换函数:
    bin() 转换为二进制
    oct() 转换为八进制
    hex() 转换为十六进制
    ord() 将字符转换成对应的ASCII码值
    chr() 将ASCII码值转换成对应的字符
    补充:
    1.enumerate() #返回一个可以枚举的对象
    2.filter() #过滤器
    3.map() #加工。对于参数iterable中的每个元素都应用fuction函数,并返回一个map对象
    4.zip() #将对象逐一配对

    example:

    li =[1,2,3,4]
    sum(li) #10
    
    abs(-12) #绝对值 12
    
    round(1.4) #四舍五入 1
    round(1.445,2) #保留两位小数 1.45
    
    bin(5)  #二进制 0101
    
    oct(8)  #八进制  %o
    hex(10) #16进制 A
    
    ord('a') #将字符转换成对应的ASCII码值
    ord('A')
    chr(65) #将ASCII码值转换成对应的字符
    
    
    #1.enumerate   #返回一个可以枚举的enumerate对象  (index,value)
    li = ['a','c','b'] 
    list(enumerate(li)) # 通过list转换成列表 [(0, 'a'), (1, 'c'), (2, 'b')]
    
    dict(enumerate(li))  #也可以通过dict转成字典 {0: 'a', 1: 'c', 2: 'b'}
    
    #注意  集合 ,字典,是无序的,没用索引。 通过enumerate可以返回(伪索引,value)
    se = {1,2,3,'asd',5}
    
    list(enumerate(se))  # [(0, 1), (1, 'asd'), (2, 2), (3, 3), (4, 5)]
    dict(enumerate(se)) # {0: 1, 1: 'asd', 2: 2, 3: 3, 4: 5}
    
    
    #2.filter() #过滤器,生成一个当参数传入函数结果为True的可迭代对象
    li =[1,2,3,6,7,8]
    def test(x):
        return x>5
    
    list(filter(test,li)) #[6, 7, 8]  
    #lambda 凡是可以用到简单函数地方,都可以用lambda
    list(filter(lambda x:x>5,li)) #[6, 7, 8]  
    
    
    # 3.map() #加工
    li =[1,2,3,6,7,8]
    
    list(map(str,li))   #把各个元素转换成字符串 ['1', '2', '3', '6', '7', '8']
    
    #每一个元素加一个 1
    list(map(lambda x:x+1,li)) # [2, 3, 4, 7, 8, 9]
    
    # zip() #将对象逐一配对,按照短序列来生成
    li2 =[1,2,3]
    tu = ('a','b','c','e')
    list(zip(li2,tu))  # [(1, 'a'), (2, 'b'), (3, 'c')]
    dict(zip(li2,tu))  # {1: 'a', 2: 'b', 3: 'c'}

    2.函数内变量的作用域

    变量的作用域与其定义的方式有关:
    局部变量: 变量在函数内部定义,则变量的作用域在函数内部
    全局变量:变量在函数外部定义的,则变量的作用域是全局

    global:用来在函数或其他局部作用域中,声明全局变量。 (作用于全局)
    nonlocal:用来在函数或其他作用域中,声明外层(非全局)变量。(作用于局部)

    使用global情况:
    全局变量可以在函数内部访问,但是不能改变
    如果在函数内部想修改全局变量,可以用 global 来修饰变量

    局部变量只能在局部进行访问和修改。
    如果在函数外部,想访问局部变量,也可以用 global,将局部变量声明为全局变量

    使用nonlocal的情况:
    当里层局部,需要修改外层局部时,需要使用nonlocal。 (如嵌套函数)


    总结:
    global :函数中,需要修改全局变量时,用global
    nonlocal:当里层局部,需要修改外层局部时,需要使用nonlocal。
    (局部调用局部,使用nonlocal)

    '''
    全局变量可以在函数内部访问,但是不能改变
    如果在函数内部想修改全局变量,可以用 global 来修饰变量
    
    '''
    
    a = 10 #全局变量
    def test1():
        b = 5 #局部变量
        print('局部访问全局变量 a:',a)  #局部可以访问,全局变量
        #a +=1   #全局变量可以在函数内部访问,但是不能改变
     
    
    
    def test2():
        global a  #全局声明
        a +=1
        print('内部修改全局变量 a:',a)
    
    
    
    def test3():  # global 只对当前函数起作用
        #global a
        a +=1
        print('teat3修改全局 a',a)
    
    
    '''
    局部变量只能在局部进行访问和修改。
    如果在函数外部,想访问局部变量,也可以用 global,将局部变量声明为全局变量
    '''
    def test4():
        global b 
        b = 4
        b+=1
        a = 21
        print('局部变量 b:',b)
    
    
    
    
    ## 使用nonlocal的情况
    
    #内嵌函数
    
    def test5():
        c = 2
        print('局部外层 c',c)
        def test6():
            d = 5
            print('局部里层 d',d)
        test6()
    
    
    # nonlocal
    
    
    c = 11
    def test7():
        c = 2       #声明外层(非全局)变量
        print('局部外层 c',c)
        def test8():
            d = 5
            print('局部里层 d',d)
            nonlocal c 
            #global c   
            c += 1   #当里层局部,需要修改外层局部时
            print('当里层局部,需要修改外层局部 C ',c)
        test8()

    3.内嵌函数和闭包

    内嵌函数: 在函数内部定义函数,就是函数里面嵌套函数

    闭包:一个闭包就是你调用了一个函数A,这个函数A返回了一个函数B给你。这个返回的函数B就叫做闭包。(但是B函数,一定要是嵌套在函数A里面) 。你在调用函数A的时候传递的参数就是自由变量。

    总结:一个函数里面嵌套一个函数,调用外面这个函数,就返回里面嵌套的函数。

    example:

    def test9(name):
        
       def test10(age):
           print('name',name,'age',age)
           
       return test10
    
    f10 = test9('jianeng')
    f10 (18)
    问题:以下函数算不算闭包呢?
    def test12():
        print('12')
        def test13():
            print('13')
            def test14():
                print('14') 
            return test14()
        return test13()
     

    4.递归函数

    递归: 函数调用自己本身

    递归的核心:
    1.递归推导式
    2.递归终止条件

    不过虽然递归很方便,但是尽量少用,以防栈溢出,而且会计算效率不高。

    '''
    例题:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。
           问第4个人岁数,他说比第3个人大2岁。
           问第三个人,又说比第2人大两岁。
           问第2个人,说比第一个人大两岁。
           最后问第一个人,他说是10岁。
           请问第五个人多少岁?
    '''
    
    '  n1      n2        n3         n4      n5    '
    
    #   10    n1 +2    n2 +2      n3 +2       n4+2
    
    
    #for  循环
    def age(n):
        age = 10
        for i in range(1,n):
            age = age +2
        print('最后一个人,是%s 岁'%age)
    
    
    
    ### 递归
    def age2(n):
        if n == 1:
            return 10
        else:
            return age2(n-1) +2
    ##要计算age2(n)的值,程序会先去计算age2(n-1)的值,要计算 age2(n-1)的值,程序要计算age2(n-2)的值...直到n==1的时候,程序算出了age2(1)的值,再把值拿到age2(2)里面...以此类推,算出age2(n)
    
    ### 阶层   1!=1*1   2!=2*1  3!=3*2*1   4!=4*3*2*1
    
    #          1!     2! =2*1! 3!=3*2!   4! =4 *3!
    
    
    #推导式 : n! = n * (n-1) !
    #终止条件:  n == 1   return 1
    
    
    def jie(n):
        if n ==1:
            return 1
        else:
            return jie(n-1) *n
    
    

    5.作业

    1、定义一个函数,输入一个序列(序列元素是同种类型),判断序列是顺序还是逆序,顺序输出UP,逆序输出DOWN,否则输出None (sorted)

    def judge_seq(seq):
        se = list(seq)
        print(se)
        if sorted(se) == se:
            return 'up'
        elif sorted(se,reverse=True)== se:  #降序逆序
            return 'DOWM'
        else:   # sorted(se) != se
            return 'None'
    View Code

    2、写一个函数,对列表li = [9,8,3,2,6,4,5,7,1],进行从小到大的排序,最后返回li(用冒泡排序写)

    li=[9,8,7,6,5,4,3,2,1]
    def li_sort(li):
        print(li)
        for j in range(len(li)-1):
            for i in range(len(li)-1):
                if li[i] > li[i+1]:
                    li[i],li[i+1] = li[i+1],li[i]
        print(li)
    View Code

    3、一个列表,有4个由数字组成的长度为4的元组,对这四个元组,按每个元组的第2个数字大小排序

    lis = [(2,3,4,5),(1,8,6,7),(6,0,1,9),(9,6,3,1)]
    
    lis.sort(key=lambda a:a[1])  
    View Code

    4、思考题:有一个名为list_apd的函数,如下所示,请你多次调用这个函数,对比返回值,是否与你预期的一致?

    def list_apd(b,a=[]):   
        a.append(b)
        return a
    '''不一致,比如当我第一次调用 list_apd(1)时,返回为[1],再次调用list_apd(1),
    返回值却是 [1,1],这与我所想的不一样,如果想改善应该这么写'''
    
    
    def list_apd(b,a=None):
        if a = None:
            a=[]
        a.append(b)
        return a
    
    #默认参数 必须指向不可变对象,防止逻辑错误
    View Code
  • 相关阅读:
    Qt之qInstallMessageHandler(重定向至文件)
    linux下MySQL安装及设置
    Apache2 同源策略解决方案
    BSD和云 – 不可错过的BSD聚会
    Nginx转发地址解决跨域问题
    Nginx下css的链接问题
    nginx 基本操作
    Azure 媒体服务可将优质内容传输至 Apple TV
    支付宝接口
    drf过滤组件
  • 原文地址:https://www.cnblogs.com/woaixuexi9999/p/9215441.html
Copyright © 2011-2022 走看看