參考python 生成器和迭代器有這篇就夠了
python中迭代器和生成器
1、可以使用isinstance()判斷乙個物件是否為可iterable可迭代物件
from collections import iterable
print
(isinstance([
], iterable)
)print
(isinstance
(, iterable)
)print
(isinstance
("abc"
, iterable)
)
執行結果
true
true
true
2、可以使用isinstance()判斷乙個物件是否是iterator迭代器
from collections import iterator
print
(isinstance
((x for x in
range(10
)), iterator)
)print
(isinstance([
], iterator)
)print
(isinstance
(, iterator)
)print
(isinstance
('abc'
, iterator)
)
執行結果
true
false
false
false
3、型別示例
s=
'hello'
#字串是可迭代物件,但不是迭代器l=[
1,2,
3,4]
#列表是可迭代物件,但不是迭代器t=(
1,2,
3)#元組是可迭代物件,但不是迭代器
d=#字典是可迭代物件,但不是迭代器
set=
#集合是可迭代物件,但不是迭代器
# *************************************
f=open
('test.txt'
)#檔案是可迭代物件,是迭代器
list、dict、str雖然是iterable(可迭代物件),卻不是iterator(迭代器),生成器都是iterator(迭代器)。
4、python3的for迴圈本質上就是通過不斷呼叫next()函式實現的
lst=[1
,2,3
,4,5
]for x in lst:
pass
實際上完全等價於
lst=[1
,2,3
,4,5
]# 首先獲得iterator物件:
it = lst.__iter__(
)# 迴圈:
while
true
:try
:# 獲得下乙個值:
x =next
(it)
except stopiteration:
# 遇到stopiteration就退出迴圈
break
5、小結
1、定義
2、生成器的三種建立辦法:
3、那麼,生成器是怎麼呼叫執行的呢?只需要了解下面幾條規則即可:
1、常規函式的定義,使用yield語句而不是return語句返回結果。yield語句語句一次返回乙個結果,在每個結果中間,掛起函式的狀態,以便下次從它離開的地方繼續執行。
def
test()
:print
(123
)#當生成器函式被呼叫時,函式體的**不會被執行,這裡的print(123),會在第一次next時才執行
yield
1yield
2yield
3
obj=test(
)print
(obj)
print
(obj.__next__())
print
(obj.__next__())
print
(obj.__next__())
#print(obj.__next__()) #報錯,超出下標索引
執行結果
2、對yield的總結
(1)通常的for…in…迴圈中,in後面是乙個陣列,這個陣列就是乙個可迭代物件,類似的還有鍊錶,字串,檔案。他可以是a = [1,2,3],也可以是a = [x*x for x in range(3)]。
它的缺點也很明顯,就是所有資料都在記憶體裡面,如果有海量的資料,將會非常耗記憶體。
(2)生成器是可以迭代的,但是只可以讀取它一次。因為用的時候才生成,比如a = (x*x for x in range(3))。!!!注意這裡是小括號而不是方括號。
(3)生成器(generator)能夠迭代的關鍵是他有next()方法,工作原理就是通過重複呼叫next()方法,直到捕獲乙個異常。
(4)帶有yield的函式不再是乙個普通的函式,而是乙個生成器generator,可用於迭代
(6)yield就是return返回的乙個值,並且記住這個返回的位置。下一次迭代就從這個位置開始。
(7)帶有yield的函式不僅僅是只用於for迴圈,而且可用於某個函式的引數,只要這個函式的引數也允許迭代引數。
(8)send()和next()的區別就在於send可傳遞引數給yield表示式,這時候傳遞的引數就會作為yield表示式的值,而yield的引數是返回給呼叫者的值,也就是說send可以強行修改上乙個yield表示式值。
(9)send()和next()都有返回值,他們的返回值是當前迭代遇到的yield的時候,yield後面表示式的值,其實就是當前迭代yield後面的引數。
(10)第一次呼叫時候必須先next()或send(),否則會報錯,send後之所以為none是因為這時候沒有上乙個yield,所以也可以認為next()等同於send(none)
1、使用列表推導式,將會一次產生所有結果:
語法 [ 最終結果(變數) for 變數 in 可迭代物件 ]
squares =
[x**
2for x in
range(5
)]print
(squares)
執行結果
[0,
1,4,
9,16]
2、將列表推導的中括號,替換成圓括號,就是乙個生成器表示式:
squares =
(x **
2for x in
range(5
))print
(squares)
#at 0x0000026d0361d048>
#next(squares)和squares.__next__()是等價的
print
(next
(squares))#0
print
(next
(squares))#1
print
(squares.__next__())
#4print
(squares.__next__())
#9print
(squares.__next__())
#16print
(squares.__next__())
#報錯,超出索引下標
執行結果
3、兩者轉換
print
(list
(x**
2for x in
range(5)))
Python迭代器和生成器
先說迭代器,對於string list dict tuple等這類容器物件,使用for迴圈遍歷是很方便的。在後台for語句對容器物件呼叫iter 函式,iter 是python的內建函式。iter 會返回乙個定義了next 方法的迭代器物件,它在容器中逐個訪問容器內元素,next 也是python的...
Python迭代器和生成器
迭代器是訪問集合元素的一種方法 是可以記住遍歷的位置的物件。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問 他有兩個基本的方法,iter 和next 字串,列表或遠足物件都可以用於建立迭代器 list1 1,2,3,4 it1 iter list1 建立迭代器物件 print next ...
python 迭代器和生成器
迭代器是訪問集合元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因為人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可...