🍖匿名函數

引入

1.編程範式

  • 編程範式指的是編程的套路
  • 主要的套路有三種 : 命令式編程, 函數式編程, 邏輯式編程
  • 常見的面向對象就是命令式編程, 常見的面向過程就是邏輯式編程

2.函數式

  • 什麼是函數式
🍋函數式編程中的函數指的並非編程語言中的函數(或方法)
🍋它指的是數學意義上的函數,即映射關係(如:y = f(x)),就是 y 和 x 的對應關係
  • 函數式與邏輯式
🍋比起邏輯式, 函數式更加註重的是執行結果並不是執行的過程
  • Python提供的函數式編程特性
🍋Python並非一門函數式的編程語言,但卻提供了不少函數式編程的特性
🍋好比 : lambda, max, min, map, reduce, filter

一.匿名函數

1.什麼是匿名函數

  • 沒有名字的函數

2.應用場景

  • 臨時用一次, 一般用於與其餘函數配合使用

3.匿名函數的強調點

  • 匿名函數的目的就是要沒有名字, 給匿名函數賦值一個名字沒有意義
  • 匿名函數的參數規則, 做用域關係與有名函數是同樣的
  • 匿名函數的函數體一般應該是一個表達式, 該表達式必須要有一個返回值

4.匿名函數與有名函數的對比

  • 有名函數
🍋有函數名,循環使用,保存了名字,經過名字就能夠重複引用函數
def foo(x,y):
    return x**y
foo(2,3)  # 8
  • 匿名函數
🍋沒有函數名,一次性使用,隨時隨地定義
f = lambda x,y:x ** y
print(f(2,4))  # 16
# 通常配合應用 : max, min, sorted, map, reduce, filter

5.匿名函數的調用方式

  • 方式一 : 直接加括號執行
res = (lambda x, y: x + y)(7,8)
print(res)  # 15
  • 方式二 : 給函數指定名字
f = lambda x,y:x ** y
print(f(2,4))  # 16
🍋匿名函數的本質就是沒有名字,這裏指定名字是沒有意義的(匿名函數只用於臨時調用一次)
🍋匿名函數通常用來與其餘函數配合使用,如下來展開介紹

二.匿名函數的應用

1.max( ) : 最大值

  • 接收兩個參數 : ([可迭代對象],[函數])

2.min( ) : 最小值

  • 接收兩個參數 : ([可迭代對象],[函數])

3.sorted( ) : 排序

  • 接收三個參數 : ([可迭代對象],[函數],[排列順序])python

  • 若是傳入的可迭代對象是字典, 默認是按照字典的 "key" 來進行排序的編程

    • sorted 函數會迭代可迭代對象中的每一個元素, 把迭代後獲得的值依次傳給匿名函數
    • 若是是字典,那麼迭代之後傳給字典的就是 key, 最終,以匿名函數的返回值做爲比較依據
    • 好比傳入的是字典, 默認迭代的就是字典的 key, 那麼返回的只就是字典的 key, 雖然你是用 value來進行比較的
  • reverse參數 : "False"表明從小到大, "True"表明的是從大到小編程語言

🍋以每一個人的薪資來作比較
salaries = {
    'song' : 1000,
    'hai' : 10000,
    'xing' : 100000,
    'shawn' : 1000000,
}

🍋"max"接收兩個參數([可迭代對象],[函數]),函數循環取的是"salaries[k]",而後進行比較,返回的是"key"
print(max(salaries,key=lambda k:salaries[k]))    # shawn

🍋"min"接收兩個參數([可迭代對象],[函數]),函數循環取的是"salaries[k]",而後進行比較,返回的是"key"
print(min(salaries,key=lambda k:salaries[k]))    # song

🍋"sorted"接收三個參數([可迭代對象],[函數],[排列順序]),函數循環取的是"salaries[k]",而後進行排序,默認排序從小到大
print(sorted(salaries,key=lambda k:salaries[k]))  # ['song', 'hai', 'xing', 'shawn']

🍋排序加上順序參數"reverse","False"表明從小到大,"True"表明的是從大到小
print(sorted(salaries,key=lambda k:salaries[k],reverse=True))  # ['shawn', 'xing', 'hai', 'song']

4.map( ) : 映射

  • 接收兩個參數 : ([函數],[可迭代對象])
  • 運行原理 : map 函數遍歷可迭代對象中的每一個元素, 把遍歷獲得的值當作參數傳給匿名函數, 以返回值的處理結果當作返回值返回
  • map 獲得的結果是迭代器對象
🍋將"nums"裏面的只都進行平方計算
nums = [1,2,3,4,5,6,7]

res = map(lambda x:x**2,nums)
print(res.__next__())  # 這是迭代器對象的一個方法,每次 next 都取出一個值(說明了獲得的結果是一個迭代器)
print(list(res))       # [1, 4, 9, 16, 25, 36, 49]

🍋生成器表達式來替代"map"
nums = [1,2,3,4,5,6,7]

res = (i ** 2 for i in nums)
print(res)  # 獲得的是一個生成器 <generator object <genexpr> at 0x0000015FD8EDAAC8>
print(res.__next__())  # 1
print(res.__next__())  # 4
print(res.__next__())  # 9
print(res.__next__())  # 16
...

🍋需求 : "song"加上"_hp"結尾,其餘的加上"_np"結尾
names = ["song","hai","xing","shawn"]

res = map(lambda i:i+"_hp" if i == "song" else i + "_np", names)  # 三元表達式
print(res)       # 迭代器對象  <map object at 0x000001A1C34DFBC8>
print(list(res)) # ['song_hp', 'hai_np', 'xing_np', 'shawn_np']

5.reduce( ) : 合併

  • 接收三個參數 : ([函數],[可迭代對象],[初始值])函數式編程

  • **reduce **在python2中是內置函數, 在python3中被集成到模塊 functools 中, 須要導入使用函數

  • 運行原理 : 以初始值做爲第一個參數傳給 x , 而後迭代傳入的可迭代對象, 拿到的值 y 與 x 相加劇新賦值給 x , 再次迭代取值, 周而復始, 直到迭代器被迭代完code

🍋需求 : 求和
from functools import reduce

res1 = reduce(lambda x,y: x + y , range(1,10),0)  # 從 0 開始,迭代相加(9)次
res2 = reduce(lambda x,y: x + y , range(1,10),1)  # 從 1 開始,迭代相加(9)次
res3 = reduce(lambda x,y: x + y , range(1,100))   # 不寫初始值默認就是 0
print(res1)  # 0+1+2+3+4+5+6+7+8+9=45
print(res2)  # 1+1+2+3+4+5+6+7+8+9=46
print(res3)  # 45

🍋列表求和
array = [1, 4, 9, 16, 25]

res = reduce(lambda x, y: x + y, array)
print(res)  # 55

6.filten( ) : 過濾

  • 接收兩個參數 : ([函數],[可迭代對象])
  • 遍歷可迭代對象, 過濾出結果爲真的元素, 若是是字典, 最終返回的結果是字典的 key
  • filten 返回的結果是迭代器
🍋需求 : 返回以"_sb"結尾的元素
names = ['song', 'hai_sb', 'xing','shi_sb','nb_sb']

res = filter(lambda x:True if x.endswith('sb') else False,names)  #三元表達式
res = filter(lambda x:x.endswith('sb'),names)
print(res)         # <filter object at 0x000001445164FC08>
print(list(res))   # ['hai_sb', 'shi_sb', 'nb_sb']

🍋過濾大於或等於 23 的數
l = [12,23,45,10,25,58,47,69]
res = filter(lambda x:x >= 23,l)
print(res)        # <filter object at 0x00000227F5510708>
print(list(res))  # [23, 45, 25, 58, 47, 69]

🍋過濾薪資大於 30000 的小夥
salaries = {
    'song' : 1000,
    'hai' : 10000,
    'xing' : 100000,
    'shawn' : 1000000,
}

res = filter(lambda k:salaries[k] >30000 ,salaries)
print(res)       # <filter object at 0x000001CFC1138F48>
print(list(res)  # ['xing', 'shawn']
相關文章
相關標籤/搜索