迭代器
"""
迭代器:
能被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對(duì)象稱為迭代器(Iterator 迭代器是對(duì)象)
概念:
迭代器指的是迭代取值的工具,迭代是一個(gè)重復(fù)的過程,每次重復(fù)都是基于上一次的結(jié)果而繼續(xù)的,
單純的重復(fù)并不是迭代
特征:
并不依賴索引,而通過next指針(內(nèi)存地址尋址)迭代所有數(shù)據(jù),一次只取一個(gè)值,
而不是一股腦的把所有數(shù)據(jù)放進(jìn)內(nèi)存.大大節(jié)省空間,
"""
一.可迭代對(duì)象
內(nèi)置函數(shù): dir
獲取當(dāng)前對(duì)象的內(nèi)置成員
setvar = {"王同培","馬春配","趙萬里","趙沈陽"}
# 獲取當(dāng)前對(duì)象的內(nèi)置成員
lst = dir(setvar)
print(lst)
# 判斷是否是可迭代對(duì)象
res = "__iter__" in lst
print(res) # True
for i in setvar:
print(i)
二.迭代器
"""
for循環(huán)之所以可以遍歷所有的數(shù)據(jù),是因?yàn)榈讓邮褂昧说?通過地址尋址的方式,一個(gè)一個(gè)的找數(shù)據(jù);
可迭代對(duì)象 -> 迭代器 實(shí)際上就是從不能夠被next直接調(diào)用 -> 可以被next指針直接調(diào)用的過程
如果是可迭代對(duì)象 -> 不一定是迭代器
如果是迭代器 -> 一定是可迭代對(duì)象
"""
1.如何創(chuàng)建一個(gè)迭代器
setvar = {"王同培","馬春配","趙萬里","趙沈陽"}
it = iter(setvar)
print(it) # <set_iterator object at 0x00>
2.如何判斷一個(gè)迭代器
print(dir(it))
res = "__iter__" in dir(it) and "__next__" in dir(it)
print(res) # True
3.如何調(diào)用一個(gè)迭代器
"""next是單向不可逆的過程,一條路走到黑"""
res = next(it)
print(res) # 趙沈陽 (無序的)
res = next(it)
print(res)
res = next(it)
print(res)
res = next(it)
print(res)
# res = next(it) # 報(bào)錯(cuò) StopIteration
# print(res)
4.重置迭代器
it = iter(setvar) # 需要重新獲取迭代器
print( it.__next__() ) # 可以使用迭代器的魔法方法
print( it.__next__() )
print( it.__next__() )
print( it.__next__() )
5.調(diào)用迭代器的其他方法
# 1 for調(diào)用
it = iter(setvar)
for i in it:
print(i)
# 2 for + next
it = iter(setvar)
for i in range(2):
print( next(it) )
print( next(it) ) # 第三個(gè)元素
print( next(it) )
# print( next(it) ) # error 超出了尋址范圍
6.判斷 迭代器Iterator/可迭代對(duì)象Iterable 的其他方法
# 從...模塊 引入...內(nèi)容
from collections import Iterator, Iterable
"""Iterator 迭代器 Iterable 可迭代的對(duì)象"""
res = isinstance(it,Iterator)
print(res)
res = isinstance(it,Iterable)
print(res)
# 迭代器一定是可迭代對(duì)象;可迭代對(duì)象不一定是迭代器
7. range()返回值是迭代器么?
print(isinstance(range(10),Iterator)) # False
print(isinstance(range(10),Iterable)) # True
# 變成迭代器
it = range(10).__iter__()
print(isinstance(it,Iterator)) # True
print(isinstance(it,Iterable)) # True
# 調(diào)用it
# next
res = next(it)
print(res)
res = next(it)
print(res)
# for
for i in it:
print(i)
高階函數(shù)
高階函數(shù) : 能夠把函數(shù)當(dāng)成參數(shù)傳遞的就是高階函數(shù) (map ,filter ,reduce , sorted)
1. map
"""
map(func,iterable)
功能: 處理數(shù)據(jù)
把iterable中的數(shù)據(jù)一個(gè)一個(gè)拿出來,扔到func做處理,通過調(diào)用迭代器來獲取返回值
參數(shù):
func : 函數(shù)(內(nèi)置函數(shù),自定義函數(shù))
iterable : 可迭代性對(duì)象 (容器類型數(shù)據(jù),range對(duì)象,迭代器)
返回值:
迭代器
"""
# (1) 把列表中的元素都變成整型
lst = ["1","2","3","4"]
lst_new = []
for i in lst:
lst_new.append(int(i))
print(lst_new)
# 用map改寫
from collections import Iterator,Iterable
it = map(int,lst) # map 返回迭代器
print(isinstance(it,Iterator))
"""
代碼解析:
第一次調(diào)用迭代器
先把列表中的第一個(gè)元素"1"拿出來扔到int中做強(qiáng)轉(zhuǎn),變成整型1返回出來
第二次調(diào)用迭代器
先把列表中的第一個(gè)元素"2"拿出來扔到int中做強(qiáng)轉(zhuǎn),變成整型2返回出來
第三次調(diào)用迭代器
先把列表中的第一個(gè)元素"3"拿出來扔到int中做強(qiáng)轉(zhuǎn),變成整型3返回出來
第四次調(diào)用迭代器
先把列表中的第一個(gè)元素"4"拿出來扔到int中做強(qiáng)轉(zhuǎn),變成整型4返回出來
"""
# 1.調(diào)用迭代器 next
print(next(it))
print(next(it))
print(next(it))
print(next(it))
# print(next(it)) # error
# 2.調(diào)用迭代器 for
print("<======>")
it = map(int,lst)
for i in it:
print(i)
# 3.調(diào)用迭代器 for + next
print("<======>")
it = map(int,lst)
for i in range(3):
print(next(it))
# 4.強(qiáng)轉(zhuǎn)迭代器 => 列表 (常用)
it = map(int,lst)
print(list(it))
# (2) [1,2,3,4] => [2,8,24,64]
# print(1 * 2 ** 1) <=> 1 << 1
# print(2 * 2 ** 2) <=> 2 << 2
lst = [1,2,3,4]
lst_new = []
for i in lst:
lst_new.append(i << i)
print(lst_new)
# map改寫
def func(n):
print(1111)
return n << n
it = map(func,lst) # 只調(diào)用map函數(shù)時(shí),func函數(shù)不會(huì)被調(diào)用
print(list(it))
"""
強(qiáng)調(diào):
只有在調(diào)用迭代器的時(shí)候,才會(huì)真正觸發(fā)map函數(shù)中的所有內(nèi)容;不調(diào)用不觸發(fā);
強(qiáng)轉(zhuǎn)迭代器時(shí),把可以調(diào)用的所有數(shù)據(jù)都放到列表中
注意點(diǎn): 形參和返回值必須寫;
"""
# (3) 已知一個(gè)字典,給你一個(gè)列表["a","b","c"] => [97,98,99]
# 字典的鍵值翻轉(zhuǎn)操作
dic = {97:"a",98:"b",99:"c"}
dic_new = {}
for k,v in dic.items():
# print(k,v) # 97 a | 98 b | 99 c
dic_new[v] = k # dic_new["a"] = 97
print(dic_new)
lst = ["a","b","c"]
lst_new = []
for i in lst:
lst_new.append(dic_new[i])
print(lst_new)
# map改寫
print("<========================>")
lst = ["a","b","c"]
lst = ["c","b","a"]
lst = ("c","b","a")
# func 實(shí)現(xiàn)字典的翻轉(zhuǎn),通過給與a,b,c三個(gè)鍵,得到對(duì)應(yīng)的ascii碼,通過list強(qiáng)轉(zhuǎn)得到列表
def func(n):
print(n)
dic = {97:"a",98:"b",99:"c"}
dic_new = {}
for k,v in dic.items():
dic_new[v] = k
print(dic_new) # {'a': 97, 'b': 98, 'c': 99}
return dic_new[n]
it = map(func,lst)
print(list(it))
2. reduce
"""
reduce(func,iterable)
功能: 計(jì)算數(shù)據(jù)
把iterable中的前兩個(gè)數(shù)據(jù)扔到func函數(shù)中做計(jì)算,把計(jì)算的結(jié)果和iterable中第三個(gè)值在繼續(xù)扔到func中做計(jì)算
以此類推 ...
最后返回計(jì)算的結(jié)果
參數(shù):
func: 自定義函數(shù)
iterable : 可迭代對(duì)象 (容器類型數(shù)據(jù) range對(duì)象 迭代器)
返回值:
計(jì)算的結(jié)果
"""
案例:文章來源:http://www.zghlxwxcb.cn/news/detail-431759.html
# (1) [7,7,5,8] => 7758
lst = [7,7,5,8]
# 方法一
strvar = ""
for i in lst:
strvar += str(i)
res = int(strvar)
print(res , type(res))
# 方法二
"""
7 * 10 + 7 = 77
77 * 10 + 5 = 775
775 * 10 + 8 = 7758
"""
# 1.先變成迭代器
it = iter(lst)
# 2.取出兩個(gè)值
num1 = next(it)
num2 = next(it)
print(num1,num2)
# 做計(jì)算
total = num1 * 10 + num2
print(total) # 77
# 3.把計(jì)算的結(jié)果在和剩下的數(shù)據(jù)做計(jì)算
for num in it:
total = total * 10 + num
# 4.返回最后的結(jié)果
print(total , type(total))
# reduce改寫
'''從...functools模塊, 引入 .. reduce方法'''
from functools import reduce
lst = [7,7,5,8]
def func(x,y):
# print(x,y)
return x * 10 + y
res = reduce(func,lst)
print(res)
# 使用lambda 進(jìn)行改造
print(reduce(lambda x,y: x*10 + y,lst))
# (2) "123" => 123 不使用int的情況下實(shí)現(xiàn)該操作;
strvar = "123"
def func(x,y):
return x * 10 + y # 字符串的拼接
# 把字符串"123" 處理成數(shù)字的123
def func2(n):
# dic = {"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}
dic = {}
for i in range(10):
dic[str(i)] = i
return dic[n]
it = map(func2,strvar)
# res = reduce(func,it)
# print(res,type(res))
# 簡寫
print(reduce(lambda x,y: x*10 + y,it))
3. filter
"""
filter(func,iterable)
功能: 過濾數(shù)據(jù)
在自定義的函數(shù)中,
如果返回True, 該數(shù)據(jù)保留
如果返回False,該數(shù)據(jù)舍棄
參數(shù):
func: 自定義函數(shù)
iterable : 可迭代對(duì)象 (容器類型數(shù)據(jù) range對(duì)象 迭代器)
返回值:
迭代器
"""
# 1.只要列表中所有的偶數(shù)
lst = [1,2,34,5,65,6,56,7,56,756,7567,11]
lst_new = []
for i in lst:
if i % 2 == 0 :
lst_new.append(i)
print(lst_new)
# filter改寫
def func(n):
if n % 2 == 0:
return True
else:
return False
it = filter(func,lst)
print(list(it))
# 使用lambda 改寫
it = filter(lambda n :True if n % 2 == 0 else False , lst)
print(list(it))
print(list(filter(lambda n :True if n % 2 == 0 else False , lst)))
4. sorted
"""
sorted(iterable, *, key=函數(shù), reverse=False)
功能:排序數(shù)據(jù)
參數(shù):
iterable : 可迭代對(duì)象 (容器類型數(shù)據(jù) range對(duì)象 迭代器)
key : 指定函數(shù)(自定義/內(nèi)置)
reverse : 是否倒序
返回值:
列表
"""
# 1.從小到大
tup = (-90,89,78,3)
res = sorted(tup)
print(res,type(res)) # list
# 2.從大到小
res = sorted(tup,reverse = True)
print(res,type(res))
# 3.按照絕對(duì)值進(jìn)行排序
tup = (-90,-100,1,2)
res = sorted(tup,key=abs)
print(res)
"""
1 => abs(1) => 1
2 => abs(2) => 2
-90 => abs(-90) => 90
-100 => abs(-100) => 100
"""
# 4.按照自定義函數(shù)進(jìn)行排序
tup = (19,23,42,87)
"""
42 % 10 2 => 42
23 % 10 3 => 23
87 % 10 7 => 87
19 % 10 9 => 19
"""
def func(n):
print(n)
return n % 10
lst = sorted(tup,key = func) # 必須要用key指定
print(lst)
# 5.任意的容器類型數(shù)據(jù)都可以通過sorted排序
container = "abc"
container = [1,2,3]
container = (1,2,3)
container = {"你好","王一","你真帥"}
container = {"caixukun","xiaozhan","zhaoshenyang","wangyibo"}
container = {"ww":"英俊帥氣","zxy":"猥瑣摳腳","zwl":"斯文敗類"} # 排的是字典的鍵
print(sorted(container))
"""
# 總結(jié):
sorted (推薦使用sorted)
(1) 可以排序所有的容器類型數(shù)據(jù)
(2) 返回一個(gè)新的列表
sort
(1) 只能排序列表
(2) 基于原來的列表進(jìn)行排序
"""
推導(dǎo)式(comprehensions)
"""
推導(dǎo)式 : 通過一行循環(huán)判斷遍歷出一些列數(shù)據(jù)的方法叫做推導(dǎo)式
通過一行循環(huán)判斷,遍歷出一系列數(shù)據(jù)的方式是推導(dǎo)式
語法: val for val in Iterable (把想要的值寫在 for的左側(cè))
里面是一行循環(huán)判斷!根據(jù)套在推導(dǎo)式外層的符號(hào)判斷具體是什么類型的推導(dǎo)式
推導(dǎo)式種類三種:
[val for val in Iterable] 列表推導(dǎo)式
{val for val in Iterable} 集合推導(dǎo)式
{a:b for a,b in iterable} 字典推導(dǎo)式
"""
1.推導(dǎo)式基本語法
lst = []
for i in range(1,51):
lst.append(i)
print(lst)
# 改寫推導(dǎo)式
lst = [ i for i in range(1,51) ]
print(lst)
# 小練習(xí)
# 1.[1,2,3,4,5] => [2,4,6,8,10]
lst = [ i*2 for i in range(1,6) ]
print(lst)
2.帶有判斷條件的推導(dǎo)式
"""注意點(diǎn):for后面緊跟的判斷條件只能是 單項(xiàng)分支 ."""
"""[1,2,3,4,5,6,7,8,9,10] => [1,3,5,7,9 ... ]"""
lst = [1,2,3,4,5,6,7,8,9,10]
lst_new = []
for i in lst:
if i % 2 == 1:
lst_new.append(i)
print(lst_new)
# 改寫推導(dǎo)式
lst = [ i for i in lst if i % 2 == 1 ]
print(lst)
3.多循環(huán)推導(dǎo)式
lst1 = ["孫杰龍","陳露","曹靜怡"]
lst2 = ["王志國","鄧鵬","合理"]
lst_new = []
for i in lst1:
for j in lst2:
lst_new.append(i+"??"+j)
print(lst_new)
# 改寫推導(dǎo)式
lst = [ i+"??"+j for i in lst1 for j in lst2 ]
print(lst)
4.帶有判斷條件的多循環(huán)推導(dǎo)式
lst_new = []
for i in lst1:
for j in lst2:
if lst1.index(i) == lst2.index(j):
lst_new.append(i+"??"+j)
print(lst_new)
# 改寫推導(dǎo)式
lst = [i+"??"+j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)]
print(lst)
# 案例
lst = []
for x in range(6):
if x % 2 == 0 :
for y in range(6):
if y % 2 == 1:
lst.append( (x,y) )
print(lst)
# 推導(dǎo)式
lst = [ (x,y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1 ]
print(lst)
集合推導(dǎo)式
"""
案例:
滿足年齡在18到21,存款大于等于5000 小于等于5500的人,
開卡格式為:尊貴VIP卡老x(姓氏),否則開卡格式為:摳腳大漢卡老x(姓氏)
把開卡的種類統(tǒng)計(jì)出來
"""
lst = [
{"name":"趙沈陽","age":18,"money":3000},
{"name":"趙萬里","age":19,"money":5200},
{"name":"趙蜂擁","age":20,"money":100000},
{"name":"趙世超","age":21,"money":1000},
{"name":"王志國","age":18,"money":5500},
{"name":"王永飛","age":99,"money":5500}
]
setvar = set()
for i in lst:
print(i) # {'name': '趙沈陽', 'age': 18, 'money': 3000}
if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500:
res = "尊貴VIP卡老{}".format(i["name"][0])
else:
res = "摳腳大漢卡老{}".format(i["name"][0])
# 添加到集合中
setvar.add(res)
print(setvar)
# { 三元運(yùn)算符 + 推導(dǎo)式 }
# 三運(yùn)運(yùn)算符 + 推導(dǎo)式
setvar = { "尊貴VIP卡老{}".format(i["name"][0]) if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500 else "摳腳大漢卡老{}".format(i["name"][0]) for i in lst }
print(setvar)
字典推導(dǎo)式
1. enumerate
"""
enumerate(iterable,[start=0])
功能:枚舉 ; 將索引號(hào)和iterable中的值,一個(gè)一個(gè)拿出來配對(duì)組成元組,通過迭代器返回
參數(shù):
iterable: 可迭代性數(shù)據(jù) (常用:迭代器,容器類型數(shù)據(jù),可迭代對(duì)象range)
start: 可以選擇開始的索引號(hào)(默認(rèn)從0開始索引)
返回值:迭代器
"""
# 基本語法
from collections import Iterator,Iterable
lst =["王一","呂洞賓","何仙姑","鐵拐李","張國老","曹國舅","藍(lán)采和","韓湘子"]
it = enumerate(lst)
it = enumerate(lst,start=100)
print(isinstance(it,Iterator)) # True
# next
print( next(it) )
# for + next (推薦,數(shù)據(jù)較大時(shí)使用)
for i in range(3):
print(next(it))
# for
for i in it:
print(i)
# list 強(qiáng)轉(zhuǎn)迭代器
print(list(it))
# (1) 字典推導(dǎo)式 配合 enumerate 來實(shí)現(xiàn)
dic = {k:v for k,v in enumerate(lst,start=100)}
print(dic) # {100: '王一'}
"""
(100, '王一')
(101, '呂洞賓')
(102, '何仙姑')
(103, '鐵拐李')
(104, '張國老')
(105, '曹國舅')
(106, '藍(lán)采和')
(107, '韓湘子')
"""
# (2) 使用dict強(qiáng)轉(zhuǎn)迭代器,瞬間得到字典
dic = dict( enumerate(lst,start=100) )
print(dic)
2. zip
"""
特點(diǎn):按照索引配對(duì)
zip(iterable, ... ...)
功能: 將多個(gè)iterable中的值,一個(gè)一個(gè)拿出來配對(duì)組成元組,通過迭代器返回
iterable: 可迭代性數(shù)據(jù) (常用:迭代器,容器類型數(shù)據(jù),可迭代對(duì)象range)
返回: 迭代器
"""
# 基本語法
# lst1 = ["孫開啟","王永飛","于朝志"]
# lst2 = ["薛宇健","韓瑞曉","上朝氣"]
# lst3 = ["劉文博","歷史園","張光旭"]
# 在索引下標(biāo)同時(shí)存在時(shí),才會(huì)進(jìn)行配對(duì),否則舍棄.
lst1 = ["孫開啟","王永飛","于朝志"]
lst2 = ["薛宇健","韓瑞曉"]
lst3 = ["劉文博"]
it = zip(lst1,lst2,lst3)
print(list(it)) # [("孫開啟","薛宇健","劉文博")]
# (1) 字典推導(dǎo)式 配合 zip 來實(shí)現(xiàn)
lst_key = ["ww","axd","yyt"]
lst_val = ["王維","安曉東","楊元濤"]
# ('ww', '王維'), ('axd', '安曉東'), ('yyt', '楊元濤')
dic = {k:v for k,v in zip(lst_key , lst_val) }
print(dic)
# (2) 使用dict強(qiáng)轉(zhuǎn)迭代器,瞬間得到字典
dic = dict( zip(lst_key , lst_val) )
print(dic)
生成器
元組推導(dǎo)式是生成器(
generator
)文章來源地址http://www.zghlxwxcb.cn/news/detail-431759.html
"""
#生成器本質(zhì)是迭代器,允許自定義邏輯的迭代器
#迭代器和生成器區(qū)別:
迭代器本身是系統(tǒng)內(nèi)置的.重寫不了.
而生成器是用戶自定義的,可以重寫迭代邏輯
#生成器可以用兩種方式創(chuàng)建:
(1)生成器表達(dá)式 (里面是推導(dǎo)式,外面用圓括號(hào))
(2)生成器函數(shù) (用def定義,里面含有yield)
"""
1. 生成器表達(dá)式 (里面是推導(dǎo)式,外面用圓括號(hào))
gen = ( i for i in range(10) )
print(gen) # <generator object <genexpr> at 0x00>
# 判斷類型
from collections import Iterator,Iterable
print(isinstance(gen,Iterator)) # True
# 1.next 調(diào)用生成器
print(next(gen))
print(next(gen))
# 2.for + next 調(diào)用生成器
for i in range(3):
print(next(gen))
# 3.for 調(diào)用生成器所有數(shù)據(jù)
for i in gen:
print(i)
# 4.list強(qiáng)轉(zhuǎn)生成器,瞬間得到所有數(shù)據(jù)
gen = ( i for i in range(10) )
print(list(gen))
# print(next(gen)) # error # StopIteration
2. 生成器函數(shù)
"""
# yield 類似于 return
共同點(diǎn)在于:執(zhí)行到這句話都會(huì)把值返回出去
不同點(diǎn)在于:yield每次返回時(shí),會(huì)記住上次離開時(shí)執(zhí)行的位置 , 下次在調(diào)用生成器 , 會(huì)從上次執(zhí)行的位置往下走
而return直接終止函數(shù),每次重頭調(diào)用.
yield 6 和 yield(6) 2種寫法都可以 yield 6 更像 return 6 的寫法 推薦使用
"""
(1) 基本語法
def mygen():
print("111")
yield 1
print("222")
yield 2
print("333")
yield 3
# 初始化生成器函數(shù) => 返回生成器對(duì)象 => 簡稱生成器
gen = mygen()
# 第一次調(diào)用
res = next(gen)
print(res) # 1
# 第二次調(diào)用
res = next(gen)
print(res) # 2
# 第三次調(diào)用
res = next(gen)
print(res) # 3
# 第四次調(diào)用,會(huì)報(bào)錯(cuò)
"""
# StopIteration error
res = next(gen)
print(res)
"""
"""
# 第一次調(diào)用
print("111") yield 1 保存當(dāng)前第2行代碼的狀態(tài),把1返回,并且等待下一次調(diào)用
# 第二次調(diào)用
從上一次保存的位置2行往下走, print("222") yield 2 保存當(dāng)前第5行代碼的狀態(tài),把2返回,并且等待下一次調(diào)用
# 第三次調(diào)用
從上一次保存的位置5行往下走, print("333") yield 3 保存當(dāng)前第8行代碼的狀態(tài),把3返回,并且等待下一次調(diào)用
# 第四次調(diào)用
因?yàn)闆]有更多的yield 返回?cái)?shù)據(jù),所有停止迭代.出現(xiàn)報(bào)錯(cuò)異常.
"""
(2) 優(yōu)化生成器代碼
"""生成器應(yīng)用的場景是在大數(shù)據(jù)的范圍中使用,切記不可直接用for遍歷所有,可能無法短時(shí)間內(nèi)獲取所有數(shù)據(jù)"""
def mygen():
for i in range(1,101):
yield i
# 初始化生成器函數(shù) => 生成器
gen = mygen()
# 需要多少數(shù)據(jù),就取多少數(shù)據(jù),防止占用大內(nèi)存
for i in range(30):
num = next(gen)
print("我的球衣號(hào)碼是{}".format(num))
for i in range(40):
num = next(gen)
print("我的球衣號(hào)碼是{}".format(num))
(3) send
的使用方式 (給上一個(gè)yield
發(fā)送數(shù)據(jù))
"""
# next和send區(qū)別:
next 只能取值
send 不但能取值,還能發(fā)送值
# send注意點(diǎn):
第一個(gè) send 不能給 yield 傳值 默認(rèn)只能寫None
最后一個(gè)yield 接受不到send的發(fā)送值
"""
def mygen():
print("start")
res = yield "內(nèi)部1"
print(res,"<==內(nèi)部==>")
res = yield "內(nèi)部2"
print(res,"<==內(nèi)部==>")
res = yield "內(nèi)部3"
print(res,"<==內(nèi)部==>")
print("end")
# 初始化生成器函數(shù) => 生成器
gen = mygen()
# 第一次調(diào)用生成器
"""
第一次調(diào)用生成器時(shí),因?yàn)闆]有遇到y(tǒng)ield保存的代碼位置,
無法發(fā)送數(shù)據(jù),默認(rèn)第一次只能發(fā)送None
"""
res = gen.send(None) # 不傳None會(huì)報(bào)錯(cuò)
print(res,"<==外部==>")
# 第二次調(diào)用生成器
res = gen.send("100")
print(res,"<==外部==>")
# 第三次調(diào)用生成器
res = gen.send("200")
print(res,"<==外部==>")
# 第四次調(diào)用生成器
"""
# error, print("end")后面沒有yield,會(huì)報(bào)錯(cuò)
res = gen.send("300")
print(res,"<==外部==>")
"""
"""
使用send調(diào)用生成器,第一次發(fā)送時(shí)必須是None,因?yàn)檫€沒有遇到y(tǒng)ield保存的代碼位置
res = gen.send(None) 走到mygen生成器函數(shù)中
print("start")
res = yield "內(nèi)部1" 執(zhí)行第4行 ,保存退出,記錄當(dāng)前代碼位置,將 "內(nèi)部1" 返回
在22行接受數(shù)據(jù) res = "內(nèi)部1" print(內(nèi)部1,"<==外部==>")
第二次調(diào)用生成器
res = gen.send("100") 把100這個(gè)數(shù)據(jù)發(fā)送給上一次代碼保存的位置4行進(jìn)行接收. => 導(dǎo)致 4行 res = 100
打印5行 print(100 ,"<==內(nèi)部==>")
執(zhí)行7行 res = yield "內(nèi)部2" 保存退出,記錄當(dāng)前代碼位置,將 "內(nèi)部2" 返回
執(zhí)行26行 res = gen.send("100") => "內(nèi)部2" print("內(nèi)部2","<==外部==>")
....
依次類推 ...
到第四次調(diào)用時(shí), 因?yàn)闆]有更多的yield 返回?cái)?shù)據(jù),gen.send(300)無法接受到返回值,所以出現(xiàn)停止迭代 StopIteration的報(bào)錯(cuò),程序終止;
"""
(4) yield from
的使用
"""將一個(gè)可迭代對(duì)象變成一個(gè)迭代器返回 """
def mygen():
lst = ["張磊","李亞峰","劉一峰","王同培"]
yield from lst
# 初始化生成器函數(shù)
gen = mygen()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
# print(next(gen)) # StopIteration
(5) 案例: 斐波那契數(shù)列
# (5) 斐波那契數(shù)列
"""使用生成器分段獲取所有內(nèi)容,而不是一股腦的把所有數(shù)據(jù)全部打印"""
"""1 1 2 3 5 8 13 21 34 .... """
def mygen(maxval):
a,b = 0,1
i = 0
while i < maxval:
# print(b)
yield b
a,b = b,a+b
i += 1
# mygen(10)
gen = mygen(10)
# 第一次獲取
for i in range(3):
print(next(gen))
# 第二次獲取
for i in range(5):
print(next(gen))
到了這里,關(guān)于【python基礎(chǔ)語法六】迭代器,生成器,推導(dǎo)式和高階函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!