1. 匿名函數 傳統的函數的定義包括了:函數名 + 函數體。 def send_email(): pass # 1. 執行 send_email() # 2. 當做列表元素 data_list = [send_email, send_email, send_email ] # 3. 當做參數傳遞 o ...
1. 匿名函數
傳統的函數的定義包括了:函數名 + 函數體。
def send_email():
pass
# 1. 執行
send_email()
# 2. 當做列表元素
data_list = [send_email, send_email, send_email ]
# 3. 當做參數傳遞
other_function(send_email)
匿名函數,則是基於lambda表達式實現定義一個可以沒有名字的函數,例如:
data_list = [ lambda x:x+100, lambda x:x+110, lambda x:x+120 ]
print( data_list[0] )
f1 = lambda x:x+100
res = f1(100)
print(res)
基於Lambda定義的函數格式為:lambda 參數:函數體
-
參數,支持任意參數。
lambda x: 函數體 lambda x1,x2: 函數體 lambda *args, **kwargs: 函數體
-
函數體,只能支持單行的代碼。
def xxx(x): return x + 100 lambda x: x + 100
-
返回值,預設將函數體單行代碼執行的結果返回給函數的執行這。
func = lambda x: x + 100 v1 = func(10) print(v1) # 110
def func(a1,a2):
return a1 + a2 + 100
foo = lambda a1,a2: a1 + a2 + 100
匿名函數適用於簡單的業務處理,可以快速並簡單的創建函數。
練習題
根據函數寫寫出其匿名函數的表達方式
def func(a1,a2):
return a1 + a2
func = lambda a1,a2: a1+a2
def func(data):
return data.replace("蒼老師","***")
func= lambda data: data.replace("蒼老師","***")
def func(data):
name_list = data.replace(".")
return name_list[-1]
func = lambda data: data.replace(".")[-1]
在編寫匿名函數時,由於受限 函數體只能寫一行,所以匿名函數只能處理非常簡單的功能。
擴展:三元運算
簡單的函數,可以基於lambda表達式實現。
簡單的條件語句,可以基於三元運算實現,例如:
num = input("請寫入內容")
if "蒼老師" in num:
data = "臭不要臉"
else:
data = "正經人"
print(data)
num = input("請寫入內容")
data = "臭不要臉" if "蒼老師" in num else "正經人"
print(data)
# 結果 = 條件成立時 if 條件 else 不成立
lambda表達式和三元運算沒有任何關係,屬於兩個獨立的知識點。
掌握三元運算之後,以後再編寫匿名函數時,就可以處理再稍微複雜點的情況了,例如:
func = lambda x: "大了" if x > 66 else "小了"
v1 = func(1)
print(v1) # "小了"
v2 = func(100)
print(v2) # "大了"
2. 生成器
生成器是由函數+yield關鍵字創造出來的寫法,在特定情況下,用他可以幫助我們節省記憶體。
-
生成器函數,但函數中有yield存在時,這個函數就是生產生成器函數。
def func(): print(111) yield 1
def func(): print(111) yield 1 print(222) yield 2 print(333) yield 3 print(444)
-
生成器對象,執行生成器函數時,會返回一個生成器對象。
def func(): print(111) yield 1 print(222) yield 2 print(333) yield 3 print(444) data = func() # 執行生成器函數func,返回的生成器對象。 # 註意:執行生成器函數時,函數內部代碼不會執行。
def func(): print(111) yield 1 print(222) yield 2 print(333) yield 3 print(444) data = func() v1 = next(data) print(v1) v2 = next(data) print(v2) v3 = next(data) print(v3) v4 = next(data) print(v4) # 結束或中途遇到return,程式爆:StopIteration 錯誤
data = func() for item in data: print(item)
生成器的特點是,記錄在函數中的執行位置,下次執行next時,會從上一次的位置基礎上再繼續向下執行。
應用場景
-
假設要讓你生成 300w個隨機的4位數,並列印出來。
- 在記憶體中一次性創建300w個
- 動態創建,用一個創建一個。
import random val = random.randint(1000, 9999) print(val)
import random data_list = [] for i in range(300000000): val = random.randint(1000, 9999) data_list.append(val) # 再使用時,去 data_list 中獲取即可。 # ...
import random def gen_random_num(max_count): counter = 0 while counter < max_count: yield random.randint(1000, 9999) counter += 1 data_list = gen_random_num(3000000) # 再使用時,去 data_list 中獲取即可。
-
假設讓你從某個數據源中獲取300w條數據(後期學習操作MySQL 或 Redis等數據源再操作,瞭解思想即可)。
所以,當以後需要我們在記憶體中創建很多數據時,可以想著用基於生成器來實現一點一點生成(用一點生產一點),以節省記憶體的開銷。
擴展
def func():
print(111)
v1 = yield 1
print(v1)
print(222)
v2 = yield 2
print(v2)
print(333)
v3 = yield 3
print(v3)
print(444)
data = func()
n1 = data.send(None)
print(n1)
n2 = data.send(666)
print(n2)
n3 = data.send(777)
print(n3)
n4 = data.send(888)
print(n4)
3.內置函數
Python內部為我們提供了很多方便的內置函數,在此整理出來36個給大家來講解。
-
第1組(5個)
-
abs,絕對值
v = abs(-10)
-
pow,指數
v1 = pow(2,5) # 2的5次方 2**5 print(v1)
-
sum,求和
v1 = sum([-11, 22, 33, 44, 55]) # 可以被迭代-for迴圈 print(v1)
-
divmod,求商和餘數
v1, v2 = divmod(9, 2) print(v1, v2)
-
round,小數點後n位(四捨五入)
v1 = round(4.11786, 2) print(v1) # 4.12
-
-
第2組:(4個)
-
min,最小值
v1 = min(11, 2, 3, 4, 5, 56) print(v1) # 2
v2 = min([11, 22, 33, 44, 55]) # 迭代的類型(for迴圈) print(v2)
v3 = min([-11, 2, 33, 44, 55], key=lambda x: abs(x)) print(v3) # 2
-
max,最大值
v1 = max(11, 2, 3, 4, 5, 56) print(v1) v2 = max([11, 22, 33, 44, 55]) print(v2)
v3 = max([-11, 22, 33, 44, 55], key=lambda x: x * 10) print(v3) # 55
-
all,是否全部為True
v1 = all( [11,22,44,""] ) # False
-
any,是否存在True
v2 = any([11,22,44,""]) # True
-
-
第3組(3個)
- bin,十進位轉二進位
- oct,十進位轉八進位
- hex,十進位轉十六進位
-
第4組(2個)
-
ord,獲取字元對應的unicode碼點(十進位)
v1 = ord("武") print(v1, hex(v1))
-
chr,根據碼點(十進位)獲取對應字元
v1 = chr(27494) print(v1)
-
-
第5組(9個)
-
int
-
foat
-
str,unicode編碼
-
bytes,utf-8、gbk編碼
v1 = "武沛齊" # str類型 v2 = v1.encode('utf-8') # bytes類型 v3 = bytes(v1,encoding="utf-8") # bytes類型
-
bool
-
list
-
dict
-
tuple
-
set
-
-
第6組(13個)
-
len
-
print
-
input
-
open
-
type,獲取數據類型
v1 = "123" if type(v1) == str: pass else: pass
-
range
range(10)
-
enumerate
v1 = ["武沛齊", "alex", 'root'] for num, value in enumerate(v1, 1): print(num, value)
-
id
-
hash
v1 = hash("武沛齊")
-
help,幫助信息
- pycharm,不用
- 終端,使用
-
zip
v1 = [11, 22, 33, 44, 55, 66] v2 = [55, 66, 77, 88] v3 = [10, 20, 30, 40, 50] result = zip(v1, v2, v3) for item in result: print(item) """ (11, 55, 10) (22, 66, 20) (33, 77, 30) (44, 88, 40) """
-
callable,是否可執行,後面是否可以加括弧。
v1 = "武沛齊" v2 = lambda x: x def v3(): pass print(callable(v1)) # False print(callable(v2)) # True print(callable(v3)) # True
-
sorted,排序
v1 = sorted([11,22,33,44,55])
info = { "wupeiqi": { 'id': 10, 'age': 119 }, "root": { 'id': 20, 'age': 29 }, "seven": { 'id': 9, 'age': 9 }, "admin": { 'id': 11, 'age': 139 }, } result = sorted(info.items(), key=lambda x: x[1]['id']) print(result)
data_list = [ '1-5 編譯器和解釋器.mp4', '1-17 今日作業.mp4', '1-9 Python解釋器種類.mp4', '1-16 今日總結.mp4', '1-2 課堂筆記的創建.mp4', '1-15 Pycharm使用和破解(win系統).mp4', '1-12 python解釋器的安裝(mac系統).mp4', '1-13 python解釋器的安裝(win系統).mp4', '1-8 Python介紹.mp4', '1-7 編程語言的分類.mp4', '1-3 常見電腦基本概念.mp4', '1-14 Pycharm使用和破解(mac系統).mp4', '1-10 CPython解釋器版本.mp4', '1-1 今日概要.mp4', '1-6 學習編程本質上的三件事.mp4', '1-18 作業答案和講解.mp4', '1-4 編程語言.mp4', '1-11 環境搭建說明.mp4' ] result = sorted(data_list, key=lambda x: int(x.split(' ')[0].split("-")[-1]) ) print(result)
-
4.推導式
推導式是Python中提供了一個非常方便的功能,可以讓我們通過一行代碼實現創建list、dict、tuple、set 的同時初始化一些值。
請創建一個列表,併在列表中初始化:0、1、2、3、4、5、6、7、8、9...299 整數元素。
data = []
for i in range(300):
data.append(i)
-
列表
num_list = [ i for i in range(10)] num_list = [ [i,i] for i in range(10)] num_list = [ [i,i] for i in range(10) if i > 6 ]
-
集合
num_set = { i for i in range(10)} num_set = { (i,i,i) for i in range(10)} num_set = { (i,i,i) for i in range(10) if i>3}
-
字典
num_dict = { i:i for i in range(10)} num_dict = { i:(i,11) for i in range(10)} num_dict = { i:(i,11) for i in range(10) if i>7}
-
元組,不同於其他類型。
# 不會立即執行內部迴圈去生成數據,而是得到一個生成器。 data = (i for i in range(10)) print(data) for item in data: print(item)
練習題
-
去除列表中每個元素的
.mp4
尾碼。data_list = [ '1-5 編譯器和解釋器.mp4', '1-17 今日作業.mp4', '1-9 Python解釋器種類.mp4', '1-16 今日總結.mp4', '1-2 課堂筆記的創建.mp4', '1-15 Pycharm使用和破解(win系統).mp4', '1-12 python解釋器的安裝(mac系統).mp4', '1-13 python解釋器的安裝(win系統).mp4', '1-8 Python介紹.mp4', '1-7 編程語言的分類.mp4', '1-3 常見電腦基本概念.mp4', '1-14 Pycharm使用和破解(mac系統).mp4', '1-10 CPython解釋器版本.mp4', '1-1 今日概要.mp4', '1-6 學習編程本質上的三件事.mp4', '1-18 作業答案和講解.mp4', '1-4 編程語言.mp4', '1-11 環境搭建說明.mp4' ] result = [] for item in data_list: result.append(item.rsplit('.',1)[0]) result = [ item.rsplit('.',1)[0] for item in data_list]
-
將字典中的元素按照
鍵-值
格式化,並最終使用;
連接起來。info = { "name":"武沛齊", "email":"[email protected]", "gender":"男", } data_list = [] for k,v in info.items(): temp = "{}-{}".format(k,v) data_list.append(temp) result= ";".join(data_list) result = ";".join( [ "{}-{}".format(k,v) for k,v in info.items()] )
-
將字典按照鍵從小到大排序,然後在按照如下格式拼接起來。(微信支付API內部處理需求)
info = { 'sign_type': "MD5", 'out_refund_no': "12323", 'appid': 'wx55cca0b94f723dc7', 'mch_id': '1526049051', 'out_trade_no': "ffff", 'nonce_str': "sdfdffd", 'total_fee': 9901, 'refund_fee': 10000 } data = "&".join(["{}={}".format(key, value) for key, value in sorted(info.items(), key=lambda x: x[0])]) print(data)
-
看代碼寫結果
def func(): print(123) data_list = [func for i in range(10)] print(data_list) # [<function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>, <function func at 0x000002269F4D1D30>]
-
看代碼寫結果
def func(num): return num + 100 data_list = [func(i) for i in range(10)] print(data_list) # [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
-
看代碼寫結果(執行出錯,通過他可以讓你更好的理解執行過程)
def func(x): return x + i data_list = [func for i in range(10)] val = data_list[0](100) print(val) # 報錯,i未定義
-
看代碼寫結果(新浪微博面試題)
data_list = [lambda x: x + i for i in range(10)] # [函數,函數,函數] i=9 v1 = data_list[0](100) v2 = data_list[3](100) print(v1, v2) # 109 109
小高級
-
推導式支持嵌套
data = [ i for i in range(10)]
data = [ (i,j) for j in range(5) for i in range(10)] data = [] for j in range(5): for i in range(10): data.append((i, j)) data = [ [i, j] for j in range(5) for i in range(10)]
# 一副撲克牌 poker_list = [ (color,num) for num in range(1,14) for color in ["紅桃", "黑桃", "方片", "梅花"]] poker_list = [ [color, num] for num in range(1, 14) for color in ["紅桃", "黑桃", "方片", "梅花"]] print(poker_list)
-
燒腦面試題
def num(): return [lambda x: i * x for i in range(4)] # 1. num()並獲取返回值 [函數,函數,函數,函數] i=3 # 2. for迴圈返回值 # 3. 返回值的每個元素(2) result = [m(2) for m in num()] print(result) # [6,6,6,6]
def num(): return (lambda x: i * x for i in range(4)) # 1. num()並獲取返回值 生成器對象 # 2. for迴圈返回值 # 3. 返回值的每個元素(2) result = [m(2) for m in num()] # [0,2,4,6 ] print(result)
總結
- 匿名函數,基於lambda表達式實現一行創建一個函數。一般用於編寫簡單的函數。
- 三元運算,用一行代碼實現處理簡單的條件判斷和賦值。
- 生成器,函數中如果yield關鍵字
- 生成器函數
- 生成器對象
- 執行生成器函數中的代碼
- next
- for(常用)
- send
- 內置函數(36個)
- 推導式
- 常規操作
- 小高級操作
作業
-
看代碼寫結果
v = [lambda: x for x in range(10)] print(v) # [<function <listcomp>.<lambda> at 0x000001A733E23280>, <function <listcomp>.<lambda> at 0x000001A7449C63A0>, <function <listcomp>.<lambda> at 0x000001A7449C6550>, <function <listcomp>.<lambda> at 0x000001A7452D5940>, <function <listcomp>.<lambda> at 0x000001A7452D59D0>, <function <listcomp>.<lambda> at 0x000001A7452D5A60>, <function <listcomp>.<lambda> at 0x000001A7452D5AF0>, <function <listcomp>.<lambda> at 0x000001A7452D5B80>, <function <listcomp>.<lambda> at 0x000001A7452D5C10>, <function <listcomp>.<lambda> at 0x000001A7452D5CA0>] print(v[0]) # <function <listcomp>.<lambda> at 0x000001A733E23280> print(v[0]()) # 9
-
看代碼寫結果
v = [i for i in range(10,0,-1) if i > 5] print(v) # [10, 9, 8, 7, 6]
-
看代碼寫結果
data = [lambda x:x*i for i in range(10)] print(data) # [<function <listcomp>.<lambda> at 0x0000029708933280>, <function <listcomp>.<lambda> at 0x00000297195063A0>, <function <listcomp>.<lambda> at 0x0000029719506550>, <function <listcomp>.<lambda> at 0x0000029719E15940>, <function <listcomp>.<lambda> at 0x0000029719E159D0>, <function <listcomp>.<lambda> at 0x0000029719E15A60>, <function <listcomp>.<lambda> at 0x0000029719E15AF0>, <function <listcomp>.<lambda> at 0x0000029719E15B80>, <function <listcomp>.<lambda> at 0x0000029719E15C10>, <function <listcomp>.<lambda> at 0x0000029719E15CA0>] print(data[0](2)) # 18 print(data[0](2) == data[8](2)) # True
-
請用列表推導式實現,踢出列表中的字元串,最終生成一個新的列表保存。
data_list = [11,22,33,"alex",455,'eirc'] new_data_list = [i for i in data_list if type(i) == int] # 請在[]中補充代碼實現。 # 提示:可以用type判斷類型
-
請用列表推導式實現,對data_list中的每個元素判斷,如果是字元串類型,則計算長度作為元素放在新列表的元素中;如果是整型,則讓其值+100 作為元素放在新的列表的元素中。
data_list = [11,22,33,"alex",455,'eirc'] new_data_list = [x + 100 if type(x) == int else len(x) for x in data_list] # 請在[]中補充代碼實現。 # 提示:可以基於三元運算實現
-
請使用字典推導式實現,將如果列表構造成指定格式字典.
data_list = [ (1,'alex',19), (2,'老男',84), (3,'老女',73) ] # 請使用推導式將data_list構造生如下格式: info_dict = {item[0]: item for item in data_list} """ info_dict = { 1:(1,'alex',19), 2:(2,'老男',84), 3:(3,'老女',73) } """
-
有4個人玩撲克牌比大小,請對比字典中每個人的牌的大小,並輸入優勝者的姓名(值大的勝利,不必考慮A)。
player = { "武沛齊":["紅桃",10], "alex":["紅桃",8], 'eric':["黑桃",3], 'killy':["梅花",12], }
data = sorted(player.items(), key=lambda x: x[1][1]) print(data[-1][0])
-
請編寫一個生成器函數實現生成n個斐波那契數列的值。
-
什麼是斐波那契數列?
前兩個數相加的結果,就是下一個數。 1 1 2 3 5 8 13 21 34 55 ...
-
代碼結構示例,請在此基礎上補充代碼實現。
def fib(max_count): first = 1 second = 0 count = 0 while count < max_count: next_value = first + second first = second second = next_value yield next_value count += 1 count = input("請輸入要生成斐波那契數列的個數:") count = int(count) fib_generator = fib(count) for num in fib_generator: print(num)
-