1. 程式人生 > 實用技巧 >內建函式 匿名函式 閉包 13

內建函式 匿名函式 閉包 13

  1. 匿名函式:一句話函式,比較簡單的函式。

    1. 此函式不是沒有名字,他是有名字的,他的名字就是你給其設定的變數,比如func.
    2. lambda 是定義匿名函式的關鍵字,相當於函式的def.
    3. lambda 後面直接加形參,形參加多少都可以,只要用逗號隔開就行。
    4. 返回值在冒號之後設定,返回值和正常的函式一樣,可以是任意資料型別。
    5. 匿名函式不管多複雜.只能寫一行.且邏輯結束後直接返回資料

    課上練習

    def func(a,b):
        return a + b
    # 構建匿名函式
    func1 = lambda a,b: a + b
    print(func1(1,2))
    
    接收一個可切片的資料,返回索引為0與2的對應的元素(元組形式)。
    func = lambda a : (a[0],a[2])
    print(func([222,333,666,6666]))
    
    寫匿名函式:接收兩個int引數,將較大的資料返回。
    lambda a,b : a if a > b else b
    
  2. 內建函式

    # # python 提供了68個內建函式。
    # # 今天講的這部分大部分了解即可。
    # # eval 剝去字串的外衣運算裡面的程式碼,有返回值。  **
    # s1 = '1 + 3'
    # # print(s1)
    # # print(eval(s1))  **
    # # s = '{"name": "alex"}'
    # # print(s,type(s))
    # # print(dict(s)) # 不行
    # # print(eval(s),type(eval(s)))
    # # 網路傳輸的str input 輸入的時候,sql注入等等絕對不能使用eval。
    #
    # # exec 與eval幾乎一樣, 程式碼流。
    # msg = """
    # for i in range(10):
    #     print(i)
    # """
    # # print(msg)
    # # exec(msg)
    # # hash 雜湊值
    # # print(hash('fsjkdafsda'))
    #
    # # help 幫助  **
    # # s1 = 'fjdsls'
    # # print(help(str))
    # # print(help(str.upper))
    # # s1 = 'sfsda'
    # # s1.upper()
    #
    # s1 = 'fdsklfa'
    # # s1()
    # def func():
    #     pass
    # # func
    # 
    #callable 判斷一個物件是否可被呼叫 ***
    #print(callable(s1))
    #print(callable(func))
    
    int 
    print(int(3.6))
    
    float
    print(type(3.6))
    
    print(complex(1,2))  #(1+2j)複數
    
    # bin:將十進位制轉換成二進位制並返回。  **
    # print(bin(100))
    # # oct:將十進位制轉化成八進位制字串並返回。  **
    # print(oct(10)
    # # hex:將十進位制轉化成十六進位制字串並返回。  **
    # print(hex(16))
    # print(hex(13))
    
    divmod **
    print(divmod(10,3))
    round 保留浮點數的小數位數 **
    print(round(3.1416592),2)#3.14
    pow 求 x**y次冪 (三個引數為x**y的結果對z 取餘) **
    print(pow(2,3))
    print(pow(2,3,3)) # 2**3 %3
    
    bytes ***
    s1 = 'holting'
    b = encoding='utf-8'
    print(b)
    b = bytes(s1,encoding='utf-8')
    print(b)
    
    ord 輸入字元找該字元編碼的位置
    ascii unicode
    print(ord('a'))
    print('中')# 2013 Unicode
    chr 輸入位置數字找出對應的字元 **
    print(chr(97))
    print(chr(20013)) #Unicode
    
    repr 返回一個物件的string形式(原形畢露)***
    s1 = 'holting'
    print(s1)
    print(repr(s1))
    # # msg = '我叫%s' %(s1)
    # msg = '我叫%r' %(s1)
    # print(msg)
    all 可迭代物件中,全都是Ture 才是Ture
    l1 = [1, 2, '太白', True, [1,2,3], '']
    print(all(l1))
    any 可迭代物件中,有一個Ture就是Ture
    l1 = [ 0, '太白', False, [], '',()]
    print(any(l1))
    
    print(self, *args, sep=' ', end='\n', file=None)
    print(1,2,3,4)
    print(1,2,3,4,sep='!')
    print(1, end=' ')
    print(2)
    
    # list
    # l1 = [1,2,3,4]
    # l2 = list()
    # l2 = list('fjfdsklagjsflag')
    # print(l2)
    
    dict 建立字典的幾種方式
    直接建立
    元祖的構建
    dic = dict{[(1,'one'),(2,'two'),(3,'three')]}
    dic = dic(one = 1,two=2)
    print(dic)
    formkeys
    update
    字典推導式
    
    abs()***
    print(abs(-1))
    
    sum()***
    l1 = [i for i in range(10)]
    # s1 = '12345'
    print(sum(l1))
    print(sum(l1,100))
    print(sum(s1))#錯誤
    
    reversed 返回的是一個翻轉的迭代器***
    # l1 = [i for i in range(10)]
    # # l1.reverse  # 列表的方法
    # # print(l1)
    l1 = [i for i in range(10)]
    obj = reversed(l1)
    print(l1)
    print(list(obj))
    
    zip 拉鍊方法 ***
    l1 = [1, 2, 3, 4, 5]
    tu1 = ('太白', 'b哥', '德剛')
    s1 = 'abcd'
    obj = zip(l1,tu1,s1)
    print(obj)
    for i in obj:
         print(i)
    print(list(obj))
    
    
    
    # *************  以下方法最最最重要
    min max 
    l1 = [33, 2, 3, 54, 7, -1, -9]
    # print(min(l1))
    #以絕對值的方式去最小值
    l2 = []
    func = lambda a:abs(a)
    for i in l1:
    	l2.append(func(i))
    print(min(l2))
    def abss(a):
    #     第一次:a = 33  以絕對值取最小值  33
    #     第二次:a = 2  以絕對值取最小值  2
    #     第三次:a = 3  以絕對值取最小值  2
    #     ......
    #     第六次:a = -1   以絕對值取最小值  1
    #
    #     '''
    	return abs(a)
    print(min(l1,key=abss))
    
    凡是可以加key的:它會自動的將可迭代物件中的每個元素按照順序傳入key對應的函式中,
    以返回值比較大小。
    dic = {'a': 3, 'b': 2, 'c': 1}
    # 求出值最小的鍵
    print(min(dic))#min預設會按照字典的鍵去比較大小。
    def func(a):
    	return dic[a]
    func = lambda a: dic[a]
    print(min(dic,key=lambda a:dic[a]))
    
    max pass
    
    
    # sorted  加key
    # l1 = [22, 33, 1, 2, 8, 7,6,5]
    # l2 = sorted(l1)
    # print(l1)
    # print(l2)
    
    l2 = [('大壯', 76), ('雪飛', 70), ('納欽', 94), ('張珵', 98), ('b哥',96)]
    # print(sorted(l2))
    # print(sorted(l2,key= lambda x:x[1]))  # 返回的是一個列表,預設從低到高
    # print(sorted(l2,key= lambda x:x[1],reverse=True))  # 返回的是一個列表,預設從低到高
    
    
    # filter 列表推導式的篩選模式
    # l1 = [2, 3, 4, 1, 6, 7, 8]
    # print([i for i in l1 if i > 3])  # 返回的是列表
    # ret = filter(lambda x: x > 3,l1)  # 返回的是迭代器
    # print(ret)
    # print(list(ret))
    
    # map  列表推導式的迴圈模式
    # l1 = [1, 4, 9, 16, 25]
    # print([i**2 for i in range(1,6)])  # 返回的是列表
    # ret = map(lambda x: x**2,range(1,6))  # 返回的是迭代器
    # print(ret)
    # print(list(ret))
    
    # reduce
    from functools import reduce
    def func(x,y):
        '''
        第一次:x  y  : 11  2     x + y =     記錄: 13
        第二次:x = 13   y  = 3    x +  y =   記錄: 16
        第三次  x = 16   y = 4 .......
        '''
        return x + y
    
    l = reduce(func,[11,2,3,4])
    print(l)
    
    1. 閉包:

      整個歷史中的某個商品的平均收盤價。什麼叫平局收盤價呢?就是從這個商品一出現開始,每天記錄當天價格,然後計算他的平均值:平均值要考慮直至目前為止所有的價格。

      比如大眾推出了一款新車:小白轎車。

      第一天價格為:100000元,平均收盤價:100000元

      第二天價格為:110000元,平均收盤價:(100000 + 110000)/2 元

      第三天價格為:120000元,平均收盤價:(100000 + 110000 + 120000)/3 元

    # 封閉的東西: 保證資料的安全。
    
    # 方案一:
    # l1 = []  # 全域性變數 資料不安全
    # li = []
    # def make_averager(new_value):
    #     l1.append(new_value)
    #     total = sum(l1)
    #     averager = total/len(l1)
    #     return averager
    # print(make_averager(100000))
    # print(make_averager(110000))
    # # 很多程式碼.....
    # l1.append(666)
    # print(make_averager(120000))
    # print(make_averager(90000))
    
    # 方案二: 資料安全,l1不能是全域性變數。
    # 每次執行的時候,l1列表都會重新賦值成[]
    # li = []
    # def make_averager(new_value):
    #     l1 = []
    #     l1.append(new_value)
    #     total = sum(l1)
    #     averager = total/len(l1)
    #     return averager
    # print(make_averager(100000))
    # print(make_averager(110000))
    # # 很多程式碼.....
    # print(make_averager(120000))
    # print(make_averager(90000))
    
    # 方案三: 閉包
    
    #
    def make_averager():
        l1 = []
        def averager(new_value):
            l1.append(new_value)
            print(l1)
            total = sum(l1)
            return total/len(l1)
        return averager
    
    # avg = make_averager()  # averager
    # print(avg(100000))
    # print(avg(110000))
    # print(avg(120000))
    # print(avg(190000))
    
    # def func():
    #     return 666
    #
    # ret = func()
    # print(globals())
    
    # 閉包: 多用於面試題: 什麼是閉包? 閉包有什麼作用。
    # 1,閉包只能存在巢狀函式中。
    # 2, 內層函式對外層函式非全域性變數的引用(使用),就會形成閉包。
    # 被引用的非全域性變數也稱作自由變數,這個自由變數會與內層函式產生一個繫結關係,
    # 自由變數不會再記憶體中消失。
    # 閉包的作用:保證資料的安全。
    
    # 如何判斷一個巢狀函式是不是閉包
    
    # 1,閉包只能存在巢狀函式中。
    # 2, 內層函式對外層函式非全域性變數的引用(使用),就會形成閉包。
    # 例一:
    # def wrapper():
    #     a = 1
    #     def inner():
    #         print(a)
    #     return inner
    # ret = wrapper()
    
    #
    # # 例二:
    # a = 2
    # def wrapper():
    #     def inner():
    #         print(a)
    #     return inner
    # ret = wrapper()
    
    
    # # 例三:
    #   也是閉包!
    # def wrapper(a,b):
    #     def inner():
    #         print(a)
    #         print(b)
    #     return inner
    # a = 2
    # b = 3
    # ret = wrapper(a,b)
    # print(ret.__code__.co_freevars)  # ('a', 'b')
    # 如何程式碼判斷閉包?
    
    def make_averager():
        l1 = []
        def averager(new_value):
            l1.append(new_value)
            print(l1)
            total = sum(l1)
            return total/len(l1)
        return averager
    
    avg = make_averager()  # averager
    print(avg.__code__.co_freevars)