python生成器迭代_二十、深入Python迭代器和生成器
「@Author:Runsen」
學習python的過程中,迭代器與生成器是繞不開的話題, 什么是迭代器和生成器呢?
下面我們來了解一下什么是迭代。但在了解迭代器之前,首先需要知道什么是容器。
容器
正所謂:一切都是對象,對象的抽象就是類,而對象的集合就是容器。
容器,就是有多個對象組成的東西。
比如:列表[0,1,2],元組(1,2,3),字典{’0:'0','1':"1'}集合{1,2,3}都是容器。
「所有的容器都是可迭代對象,也就是可以使用for循環(huán)遍歷元素。」
#?1、for?循環(huán)迭代字符串,?字符串之間使用空格連接
for?char?in?'RUNSEN':
print(char,?end='?')
輸出如下:
R?U?N?S?E?N
#?2、for?循環(huán)迭代?list?列表,列表元素之間使用空格連接
list1?=?[i?for?i?in?range(5)]??#?這里使用了列表生成表達式
for?num?in?list1:
print(num,?end='?')
輸出如下:
0?1?2?3?4
#?3、for?循環(huán)迭代?dict?(字典)
dict?=?{'name':?'Runsen',?'age':?'21',?'sex':?'男'}
#?迭代?dict?中的?key(默認是迭代key)
for?key?in?dict:
print(key,?end='?')
for?value?in?dict.values():
print(value,?end='?')
輸出如下:
name?age?sex
Runsen?21?男
#?4、list?中一個元素中還有多個元素
for?x,?y?in?[(1,?'a'),?(2,?'b'),?(3,?'c')]:
print(x,?y)
輸出如下:
1?a
2?b
3?c
可迭代對象
所有的容器都是可迭代對象(iterable),從專業(yè)角度來講,只要:內部含有__iter__方法的對象,就是可迭代對象。
因此,我只要使用print('__iter__' in dir(XX)),就能判斷XX是不是可迭代對象。
人們常說:列表、元組、字典、字符串都是可迭代對象。數(shù)字、布爾值都是不可迭代的。我一試便知。
list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定)
print('__iter__'?in?dir(list))
print('__iter__'?in?dir(tuple))
print('__iter__'?in?dir(dict))
print('__iter__'?in?dir(set))
print('__iter__'?in?dir(str))
print('__iter__'?in?dir(int))
print('__iter__'?in?dir(bool))
print('__iter__'?in?dir([1,2,3]))
輸出如下:
True
True
True
True
True
False
False
True
除了print('__iter__' in dir(XX))判斷是不是可迭代對象。還是一種通過Iterable和isinstance方法聯(lián)合使用,進行判斷。
from?collections?import?Iterable
print(isinstance('abc',?Iterable))
print(isinstance({1,?2,?3},?Iterable))
print(isinstance(1,?Iterable))
輸出如下:
True
True
False
「注意:list,string,tuple,dict 都屬于可迭代對象,但不是迭代器」
迭代器
迭代器(iterator)只是提供了一個 next 的方法。調用這個方法后,你要么得到這個可迭代對象的下一個對象,要么得到一個 StopIteration的錯誤。
那么,如何聲明一個可迭代對象,可以通過__iter__() 來生成可迭代對象,前提是__iter__()傳入的參數(shù)是容器。
你看下圖iter(111)是不是報錯了。
因為111不能遍歷,所以iter(111)直接報錯。
取值
上面說過:迭代器提供了一個next方法,調用這個方法,得到了容器的下一個對象或者一個stopiteration 的報錯,具體代碼如下所示。
>>>a?=?iter("123")
>>>next(a)
'1'
>>>next(a)
'2'
>>>next(a)
'3'
>>>next(a)
Traceback?(most?recent?call?last):
File?"",?line?1,?in?
StopIteration
生成器
那么什么又是生成器,和迭代器又有什么關系?
其實,生成器也是迭代器,但更加優(yōu)雅。使用生成器,我們可以實現(xiàn)與迭代器相同的功能,但不必在類中編寫iter()和next()函數(shù)
「我覺得生成器就是一個迭代器的例子。」,如果說迭代器是人,那么生成器就人中的一類人,比如黃人。
為什么會出來一個生成器,其實很簡單聲明一個迭代器很簡單,但是很容易造成內存不夠。生成器不會將集合中所有的元素都加載到內存。
比如下圖(i for i in range(1000000000)通過元組方式生成生成器。如果使用迭代器,那么當聲明迭代器就運行不了了。
[i for i in range(1000000000] 它本是一個迭代器,但因占用的內存太大了,跑不起來,于是古人引出了生成器的概念,當你用的時候,再加載到內存空間中。
在聲明生成器中,還有一種方法通過yield關鍵字。
yield和return的區(qū)別在于yield并沒有終止函數(shù),而return返回值后不再執(zhí)行函數(shù)內代碼。
對于yield,在scrapy用的多,然后我在其他地方?jīng)]有見到過。
引用yield,帶yield的函數(shù)就叫做生成器,具體示例如下所示。
def?test():
yield?1
yield?2
yield?3
t?=?test()
print(next(t))#output:1
print(next(t))#output:2
print(next(t))#output:3
print(next(t))#output:Traceback?(most?recent?call?last):StopIteration
今天也學到了很多東西呢,明天有什么新知識呢?真期待鴨。如果喜歡文章可以關注我哦~
?
本文已收錄 GitHub,傳送門~[1] ,里面更有大廠面試完整考點,歡迎 Star。
?
Reference
[1]
傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100
總結
以上是生活随笔為你收集整理的python生成器迭代_二十、深入Python迭代器和生成器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软连接
- 下一篇: springmvc重定向到另一个项目_s