生成器python
1.什麼是生成器?
生成的工具。
生成器是一個 "自定義" 的迭代器, 本質上是一個迭代器。編程
2.如何實現生成器
但凡在函數內部定義了的yield,
調用函數時,函數體代碼不會執行,
會返回一個結果,該結果就是一個生成器。函數
yield:
每一次yield都會往生成器對象中添加一個值。
- yield只能在函數內部定義
- yield能夠保存函數的暫停狀態工具
yield與return:
相同點:
返回值的個數都是無限制的。spa
不一樣點:
return只能返回一次值,yield能夠返回多個值,默認是元組,能夠修改返回類型設計
自定義的迭代器 def func(): print('開始準備下蛋') print('1---火雞蛋1') yield '火雞蛋1' print('2---火雞蛋2') yield '火雞蛋2' print('3---火雞蛋3') yield '火雞蛋3' print('取最後一個蛋,查看是否有') res是迭代器對象 res = func() 當咱們經過__next__取值時,纔會執行函數體代碼。 next(迭代器對象) print(next(res)) print(next(res)) print(next(res)) 迭代器對象.__next__() print(res.__next__()) print(res.__next__()) print(res.__next__()) print(res.__next__()) # StopIteration報錯
自定義range功能,建立一個自定義生成器code
# 循環10次 # for i in range(1, 11): # # print(i) # 1—10 # python2: range(1, 5) ---> [1, 2, 3, 4] # python3: range(1, 5) ---> range對象 ---> 生成器 ---> 迭代器 # res = range(1, 5) # print(res) # 自定義range功能,建立一個自定義的生成器 # (1, 3) # start--> 1 , end---> 5, move=2 def my_range(start, end, move=1): # while start < end: yield start start += move # g_range = my_range(1, 5) # print(g_range) # # for line in g_range: # print(line) for line in my_range(1, 5, 2): print(line)
面向過程編程對象
思想!!!
面向過程編程是一門編程思想。blog
面向 過程 編程:
核心是 '過程' 二字,過程 指的是一種解決問題的步驟,即先幹什麼再幹什麼
基於該編程思想編寫程序,就比如在設計一條工廠流水線,一種機械式的思惟方式。排序
優勢:
將複雜的問題流程化,進而簡單化
缺點:
若修改當前程序設計的某一部分, 會致使其餘部分同時須要修改, 擴展性差。
牽一髮而動全身,擴展性差。
三元表達式
能夠將if...else...分支變成一行。
語法:
條件成立返回左邊的值 if 判斷條件 else 條件不成立返回右邊的值
def max2(num1, num2): res = num1 if num1 > num2 else num2 return res res = max2(3, 2) print(res) # 需求: 讓用戶輸入用戶名,輸入的用戶若是不是tank,爲其後綴添加_DSB username = input('請輸入用戶名:').strip() new_username = username if username == 'tank' else username + '_DSB' print(new_username)
列表生成式
能夠一行實現生成列表。
語法:
list = [取出的每個值、任意值 for 可迭代對象中取出的每個值 in 可迭代對象]
# for的右邊是循環次數,而且能夠取出可迭代對象中每個值
# for的左邊能夠爲當前列表添加值
list = [值 for 可迭代對象中取出的每個值 in 可迭代對象]
list = [值 for 可迭代對象中取出的每個值 in 可迭代對象 if 判斷]
# 列表生成式 list1 = [f'1{line}' for line in range(1, 101)] print(list1) #Demo: 將name_list列表中的每個人後綴都添加_dsb name_list = ['jason', '餅哥(大臉)', 'sean', 'egon'] new_name_list = [name + '_dsb' for name in name_list] print(new_name_list) #將name_list列表中的tank過濾掉,其餘人後綴都添加_dsb name_list = ['jason', '餅哥(大臉)', 'sean', 'egon', 'tank'] new_name_list = [name + '_dsb' for name in name_list if not name == 'tank'] print(new_name_list)
生成器表達式(生成式)
- 列表生成式: 若數據量小時採用
[line for line in range(1, 6)] ---> [1, 2, 3, 4, 5]
優勢:
能夠依賴於索引取值,取值方便
缺點:
浪費資源
- 生成器生成式: 若數據量過大時採用
() ---> 返回生成器
(line for line in range(1, 6)) ---> g生成器(1, 2, 3, 4, 5)
優勢:
節省資源
缺點:
取值不方便
# 生成一個有1000個值的生成器 g = (line for line in range(1, 1000001)) # <generator object <genexpr> at 0x00000203262318E0> print(g) # 列表生成式實現 list1 = [line for line in range(1, 1000001)] print(list1) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10...]
匿名函數:
無名字的函數
# :左邊是參數, 右邊是返回值
lambda :
PS: 緣由,由於沒有名字,函數的調用 函數名 + ()
匿名函數須要一次性使用。
注意: 匿名函數單獨使用毫無心義,它必須配合 「內置函數」 一塊兒使用的纔有意義。
有名函數:
有名字的函數
func = lambda x,y:x if x > y else y print(func(2,6)) #6 calc = lambda x,y:x**y print(calc(2,5)) #32
#按年齡排序 l=[{'name':'alex','age':84},{'name':'oldboy','age':73}, {'name':'egon','age':18}] l.sort(key=lambda x:x['age']) print(l) # [{'name': 'egon', 'age': 18}, {'name': 'oldboy', 'age': 73}, {'name': 'alex', 'age': 84}]
內置函數:
range()
print()
len()
# python內部提供的內置方法
max, min, sorted, map, filter
max: 獲取可迭代對象中最大值
min: 獲取可迭代對象中最小值
sorted: 對可迭代對象進行排序
默認是: 升序
reverse=True: 降序
map: 映射
reduce: 合併
filter: 過濾
# max求最大值 max(可迭代對象) list1 = [1, 2, 3, 4, 5] # max內部會將list1中的經過for取出每個值,而且進行判斷 print(max(list1)) # dict1 = { 'tank': 1000, 'egon': 500, 'sean': 200, 'jason': 500 } # 獲取dict1中薪資最大的人的名字 # 字符串的比較: ASCII print(max(dict1, key=lambda x: dict1[x])) #tank 由於以索引判斷,因此key就是索引,參數x爲索引
# 獲取dict1中薪資最小的人的名字
print(min(dict1, key=lambda x:dict1[x]))
# sorted: 默認升序(從小到大) reverse:反轉 reverse默認是False list1 = [10, 2, 3, 4, 5] print(sorted(list1)) # reverse=True--> 降序 print(sorted(list1, reverse=True)) dict1 = { 'tank': 100, 'egon': 500, 'sean': 200, 'jason': 50 } # new_list = ['egon', 'sean', 'tank', 'jason'] new_list = sorted(dict1, key=lambda x: dict1[x], reverse=True) print(new_list)
map()
map(函數地址, 可迭代對象) ---> map對象
map會將可迭代對象中的每個值進行修改,而後映射一個map對象中,
能夠再將map對象轉換成列表/元組。
注意: 只能轉一次。
name_list = ['egon', 'jason', 'sean', '大餅', 'tank'] map_obj = map(lambda name: name + '喜歡吃生蠔' if name == 'tank' else name + 'DJB', name_list) print(map_obj) # map_obj ---> list/tuple print(list(map_obj)) # map_obj ---> 生成器(迭代器) ---> 用完後,不能再取了 print(tuple(map_obj)) # map對象只能調用一次,第二次返回空 # 結果 # <map object at 0x00000000021CF4A8> # ['egonDJB', 'jasonDJB', 'seanDJB', '大餅DJB', 'tank喜歡吃生蠔'] # ()
list1=[1,2,3,4,5] res=map(lambda x:x**2,list1) print(list(res)) # [1, 4, 9, 16, 25] def square(x): return x**2 ---------------------------------------- list1=[1,2,3,4,5] res=map(square,list1) print(list(res)) # [1, 4, 9, 16, 25]
reduce()
reduce(函數地址, 可迭代對象, 默認爲0)
reduce(函數地址, 可迭代對象, 初始值)
# reduce from functools import reduce #須要導入模塊 # 每次從可迭代對象中獲取兩個值進行合併, # 初始值: 執行reduce函數時,都是從初始值開始合併 reduce(lambda x, y: x + y, range(1, 101), 0)# 先算x=0 + y=1,和爲x再+2,和再+3...+100 # 需求: 求1——100的和 # 普通 init = 1000 for line in range(1, 101): init += line print(init) # 5050 # reduce res = reduce(lambda x, y: x + y, range(1, 101), 1000)# 先算x=1000 + y=1,和爲x再+2,和再+3...+100 print(res) # 6050
filter()
filter(函數地址, 可迭代對象) --> filter 對象
# filter name_list = ['egon_dsb', 'jason_dsb', 'sean_dsb', '大餅_dsb', 'tank'] # filter_obj = filter(lambda x: x, name_list) # 將後綴爲_dsb的名字 「過濾出來」 # filter會將函數中返回的結果爲True 對應 的參數值 「過濾出來」 # 過濾出來的值會添加到 filter對象中 filter_obj = filter(lambda name: name.endswith('_dsb'), name_list) #是否結尾爲'_dsb',若是爲true,返回那個值 print(filter_obj) #<filter object at 0x0000000001E4C5C0> print(list(filter_obj)) # ['egon_dsb', 'jason_dsb', 'sean_dsb', '大餅_dsb'] # print(tuple(filter_obj)) ---------------------------------------------------------------- name_list = ['egon_dsb', 'jason_dsb', 'sean_dsb', '大餅_dsb', 'tank'] filter_obj = filter(lambda x:x[-3:] != 'dsb',name_list) print(filter_obj) print(list(filter_obj)) # ['tank']