Python常見(jiàn)Iterable可迭代對(duì)象(建議收藏)
我們知道,可以直接作用于for循環(huán)的對(duì)象,像 list,tuple,dict 等;
統(tǒng)稱(chēng)為 可迭代對(duì)象:Iterable。
那 Python 中有哪些常見(jiàn)的 可迭代對(duì)象呢?
一、字符串 str
本質(zhì)上是字符數(shù)組。所以當(dāng)然是可迭代的。可以用 isinstance() 函數(shù)判斷一個(gè)對(duì)象是否是 Iterable 對(duì)象。
from collections.abc import Iterable
s = 'ABCDEFG'
for x in s:
print(x, end=" ")
if isinstance(s, Iterable):
print('字符串是可迭代對(duì)象') 
二、列表 list
from collections.abc import Iterable
L = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
for x in L:
print(x, end=" ")
if isinstance(L, Iterable):
print('列表是可迭代對(duì)象') 
三、列表生成式 List Comprehensions
本質(zhì)上還是列表,列表生成式更像是 Python 提供的一種語(yǔ)法糖,在運(yùn)行時(shí)替換為生成的列表。
from collections.abc import Iterable
L = [ chr(x) for x in range(65, 72)]
for x in L:
print(x, end=" ")
if isinstance(L, Iterable):
print('列表生成式是可迭代對(duì)象')
擴(kuò)展:
1、兩層的列表生成式
print( [ m+n for m in 'ABC' for n in 'XYZ' ] )

等效于
# 等效于
L = []
for m in 'ABC':
for n in 'XYZ':
L.append(m+n)
# 打印
print(L)
2、for 循環(huán)后面加上 if 判斷的列表生成式
print( [ m+n for m in 'ABC' if m != 'A' for n in 'XYZ' if n != 'X' ] )

等效于
# 等效于
L = []
for m in 'ABC':
if m != 'A':
for n in 'XYZ':
if n != 'X':
L.append(m+n)
# 打印
print(L)
3、for 循環(huán)前面加上 if 判斷的列表生成式
print( [ m+n if m != 'A' and n != 'X' else None for m in 'ABC' for n in 'XYZ' ] )

等效于
# 等效于
L = []
for m in 'ABC':
for n in 'XYZ':
if m != 'A' and n != 'X':
L.append(m+n)
else:
L.append(None)
# 打印
print(L)
4、為什么 for 循環(huán)后面的 if 不需要 else,而 for 循環(huán)前面的 if 需要 else?
因?yàn)?nbsp;for 循環(huán)后面的 if 表示的是一種過(guò)濾條件,它只需要過(guò)濾掉不需要的元素,不讓它進(jìn)入下一級(jí) for 語(yǔ)句 或者 for 前面的表達(dá)式就行。它是一種單分支的條件判斷。
就好像你去報(bào)考清華,清華招生辦只需要知道你的分?jǐn)?shù)是否達(dá)標(biāo),不達(dá)標(biāo)就過(guò)濾掉了,他不會(huì)考慮你不達(dá)標(biāo)之后的去處,是去北大,還是去農(nóng)大。
而 for 循環(huán)前面是 表達(dá)式語(yǔ)句。是表達(dá)式就需要有結(jié)果。
m+n if m != 'A' and n != 'X' else None
m+n 是 if 成立的結(jié)果,那 if 不成立的結(jié)果呢?你要告訴它。
for 循環(huán)前面的 表達(dá)式語(yǔ)句 有點(diǎn)類(lèi)似于Java的三目運(yùn)算符。
四、range 對(duì)象
無(wú)需多言,Python 迭代開(kāi)始的地方。
from collections.abc import Iterable
r = range(65, 72)
# print(r)
for x in r:
print(chr(x), end=" ")
if isinstance(r, Iterable):
print('range是可迭代對(duì)象') 
擴(kuò)展:一些特殊值
class range(stop) 默認(rèn) class range(start, stop[, step])
1、stop = 0

2、start = stop

3、start > stop

五、元組 tuple
不可變的列表,當(dāng)然也是可迭代的。
from collections.abc import Iterable
t = ( 'A', 'B', 'C', 'D', 'E', 'F', 'G' )
for x in t:
print(x, end=" ")
if isinstance(t, Iterable):
print('元組是可迭代對(duì)象')
六、字典 dict
from collections.abc import Iterable
d = { 'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7 }
for x in d:
print(x, end=" ")
if isinstance(d, Iterable):
print('字典是可迭代對(duì)象')這種方式只會(huì)迭代出字典的 key

字典的更多迭代方式,可以看我的另外一篇博文 遍歷字典
七、字典生成式 dict comprehensions
from collections.abc import Iterable
keys = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
values = [ 1, 2, 3, 4, 5, 6, 7]
d = { k : v for k, v in zip(keys, values) }
print(d)
for x in d:
print(x, end=" ")
if isinstance(d, Iterable):
print('字典生成式是可迭代對(duì)象')
八、集合 set
from collections.abc import Iterable
s = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }
for x in s:
print(x, end=" ")
if isinstance(s, Iterable):
print('集合是可迭代對(duì)象')集合是無(wú)序的,所以打印出來(lái)的元素并沒(méi)有按照定義時(shí)的順序。

九、集合生成式 set comprehensions
from collections.abc import Iterable
s = { x for x in 'ABCDEFGHIJ' if x not in 'HIJ' }
print( s )
for x in s:
print(x, end=" ")
if isinstance(s, Iterable):
print('集合生成式是可迭代對(duì)象')
十、生成器 generator
通過(guò)各種生成式,可以很方便的生成各種集合數(shù)據(jù)結(jié)構(gòu)。不過(guò)生成式有一個(gè)缺點(diǎn),就是所有元素都是一次性生成,然后放在內(nèi)存中的。內(nèi)存容量總歸是有限的。
如果元素可以按照某種算法推算出來(lái),那我們就可以在循環(huán)的過(guò)程中不斷推算出后續(xù)的元素,而不用一次性全部生成。
Python中,這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱(chēng)為生成器:generator。
創(chuàng)建生成器的一種簡(jiǎn)單的方法,就是把各種 生成式 外面的 [] 或 {} 改成 ()
列表生成器
把第三節(jié)的列表生成式改造一下,就可以得到一個(gè)列表生成器:
from collections.abc import Iterable
g = ( chr(x) for x in range(65, 72) )
print( g )
for x in g:
print(x, end=" ")
if isinstance(g, Iterable):
print('列表生成器是可迭代對(duì)象') 
字典生成器
from collections.abc import Iterable
keys = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
values = [ 1, 2, 3, 4, 5, 6, 7]
g = ( { k : v } for k, v in zip(keys, values) )
print(g)
for x in g:
print(x, end=" ")
if isinstance(g, Iterable):
print('字典生成器是可迭代對(duì)象')
集合生成器
from collections.abc import Iterable
g = ( { x } for x in 'ABCDEFGHIJ' if x not in 'HIJ' )
print(g)
for x in g:
print(x, end=" ")
if isinstance(g, Iterable):
print('集合生成器是可迭代對(duì)象') 
元組生成器
from collections.abc import Iterable
L1 = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
L2 = [ 1, 2, 3, 4, 5, 6, 7]
g = ( ( x , y ) for x, y in zip(L1, L2) )
print(g)
for x in g:
print(x, end=" ")
if isinstance(g, Iterable):
print('元組生成器是可迭代對(duì)象')
生成器 除了用 for in 迭代外,還可以通過(guò)next()函數(shù)獲得生成器的下一個(gè)返回值。
每次調(diào)用 next(g),就計(jì)算出g的下一個(gè)元素的值,直到計(jì)算到最后一個(gè)元素,沒(méi)有更多的元素時(shí),拋出StopIteration的錯(cuò)誤。
g = ( chr(x) for x in range(65, 72) ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " ) print( next(g), end=" " )

十一、生成器函數(shù)
創(chuàng)建生成器的另一種方式,是使用生成器函數(shù)。
生成器函數(shù)是一種特殊的函數(shù),使用 `yield` 語(yǔ)句來(lái)返回一個(gè)值,并暫停函數(shù)的執(zhí)行,等待下一次調(diào)用。每次調(diào)用生成器函數(shù)時(shí),它會(huì)從上一次暫停的位置繼續(xù)執(zhí)行,直到遇到下一個(gè) `yield` 語(yǔ)句或函數(shù)結(jié)束。
我們來(lái)看一個(gè)楊輝三角的生成器函數(shù):
from collections.abc import Iterator
from collections.abc import Iterable
def triangles():
L = [1]
while True:
# 第一次調(diào)用 next,保留函數(shù)現(xiàn)場(chǎng) L=[1] 返回 [1]
yield L
# 第二次調(diào)用 next,從這里開(kāi)始,取出函數(shù)現(xiàn)場(chǎng) L=[1] 執(zhí)行,然后循環(huán)
# 直到碰到 yield 關(guān)鍵字,繼續(xù)保留函數(shù)現(xiàn)場(chǎng),然后返回
L = [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1]
g = triangles()
print(g)
if isinstance( g, Iterable):
print('生成器函數(shù)是可迭代對(duì)象')
if isinstance( g, Iterator):
print('生成器函數(shù)是迭代器') 
十二、迭代器 Iterator
可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對(duì)象稱(chēng)為迭代器:Iterator。
而生成器是一種特殊的迭代器。像我們上面建的那些生成器,統(tǒng)統(tǒng)都是迭代器。
from collections.abc import Iterator
lg = ( chr(x) for x in range(65, 72) )
if isinstance(lg, Iterator):
print('列表生成器是迭代器')
keys = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
values = [ 1, 2, 3, 4, 5, 6, 7]
dg = ( { k : v } for k, v in zip(keys, values) )
if isinstance(dg, Iterator):
print('字典生成器是迭代器')
sg = ( { x } for x in 'ABCDEFGHIJ' if x not in 'HIJ' )
if isinstance(sg, Iterator):
print('集合生成器是迭代器')
L1 = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ]
L2 = [ 1, 2, 3, 4, 5, 6, 7]
tg = ( ( x , y ) for x, y in zip(L1, L2) )
if isinstance(tg, Iterator):
print('元組生成器是迭代器') 
字符串、集合數(shù)據(jù)結(jié)構(gòu),包括它們的生成式,都不是迭代器。
from collections.abc import Iterator
if isinstance( 'ABC', Iterator):
print('字符串是迭代器')
else:
print('字符串不是迭代器')
if isinstance( range(5), Iterator):
print('range對(duì)象是迭代器')
else:
print('range對(duì)象不是迭代器')
if isinstance( [], Iterator):
print('列表是迭代器')
else:
print('列表不是迭代器')
if isinstance( [ chr(x) for x in range(65, 72)], Iterator):
print('列表生成式是迭代器')
else:
print('列表生成式不是迭代器')
if isinstance( (1,), Iterator):
print('元組是迭代器')
else:
print('元組不是迭代器')
if isinstance( { }, Iterator):
print('字典是迭代器')
else:
print('字典不是迭代器')
if isinstance( { x : x**2 for x in range(5) }, Iterator):
print('字典生成式是迭代器')
else:
print('字典生成式不是迭代器')
if isinstance( { 1 }, Iterator):
print('集合是迭代器')
else:
print('集合不是迭代器')
if isinstance( { x for x in range(5) }, Iterator):
print('集合生成式是迭代器')
else:
print('集合生成式不是迭代器')

為什么list、dict、str等數(shù)據(jù)類(lèi)型不是Iterator?
"這是因?yàn)镻ython的Iterator對(duì)象表示的是一個(gè)數(shù)據(jù)流,Iterator對(duì)象可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯(cuò)誤??梢园堰@個(gè)數(shù)據(jù)流看做是一個(gè)有序序列,但我們卻不能提前知道序列的長(zhǎng)度,只能不斷通過(guò)next()函數(shù)實(shí)現(xiàn)按需計(jì)算下一個(gè)數(shù)據(jù),所以Iterator的計(jì)算是惰性的,只有在需要返回下一個(gè)數(shù)據(jù)時(shí)它才會(huì)計(jì)算。"
集合數(shù)據(jù)類(lèi)型雖然不是Iterator,不過(guò)可以通過(guò)iter()函數(shù)獲得一個(gè)Iterator對(duì)象。
Python的for循環(huán)本質(zhì)上就是通過(guò)不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的。
列表的 for 循環(huán):
L = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
for x in L:
print(x, end=" ")
print('\n等效于')
it = iter(L)
while True:
try:
x = next(it)
print(x, end=" ")
except StopIteration:
break
字典生成器 for 循環(huán):
g = ( { x : x**2} for x in range(5) )
for x in g:
print(x, end=" ")
print('\n等效于')
# 注意,在第一次 for 循環(huán)以后,生成器 g 的元素已經(jīng)被遍歷完了
# 所以需要重新新建一個(gè)生成器
g = ( { x : x**2} for x in range(5) )
while True:
try:
x = next(g)
print(x, end=" ")
except StopIteration:
break 
十三、Iterable、Iterator、集合數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系

- GitHub Copilot: 迭代器和生成器都是Python中用于處理可迭代對(duì)象的工具。
- 迭代器是一個(gè)實(shí)現(xiàn)了迭代器協(xié)議的對(duì)象,它可以被 `next()` 函數(shù)調(diào)用來(lái)返回下一個(gè)值,如果沒(méi)有更多的值可以返回,那么就會(huì)拋出 `StopIteration` 異常。迭代器可以用于遍歷序列、集合和其他可迭代對(duì)象,例如列表、元組、字典和文件等。Python中的內(nèi)置函數(shù) `iter()` 可以將一個(gè)可迭代對(duì)象轉(zhuǎn)換為一個(gè)迭代器。
- 生成器是一種特殊的迭代器,它可以通過(guò)函數(shù)來(lái)創(chuàng)建。生成器函數(shù)使用 `yield` 語(yǔ)句來(lái)返回一個(gè)值,并暫停函數(shù)的執(zhí)行,等待下一次調(diào)用。每次調(diào)用生成器函數(shù)時(shí),它會(huì)從上一次暫停的位置繼續(xù)執(zhí)行,直到遇到下一個(gè) `yield` 語(yǔ)句或函數(shù)結(jié)束。生成器可以用于生成大量數(shù)據(jù)或處理無(wú)限序列,例如斐波那契數(shù)列和素?cái)?shù)序列等。
到此這篇關(guān)于Python常見(jiàn)Iterable可迭代對(duì)象(建議收藏)的文章就介紹到這了,更多相關(guān)Python Iterable可迭代對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Python去除字符串中某個(gè)字符的多種實(shí)現(xiàn)方式比較
python中字符串是不可變的,所以無(wú)法直接刪除字符串之間的特定字符,下面這篇文章主要給大家介紹了關(guān)于使用Python去除字符串中某個(gè)字符的多種實(shí)現(xiàn)方式比較的相關(guān)資料,需要的朋友可以參考下2022-06-06
Python數(shù)據(jù)分析之?Matplotlib?3D圖詳情
本文主要介紹了Python數(shù)據(jù)分析之Matplotlib 3D圖詳情,Matplotlib提供了mpl_toolkits.mplot3d工具包來(lái)進(jìn)行3D圖表的繪制,下文總結(jié)了更多相關(guān)資料,需要的小伙伴可以參考一下2022-05-05
Python中模塊pymysql查詢結(jié)果后如何獲取字段列表
pymsql是Python中操作MySQL的模塊,其使用方法和MySQLdb幾乎相同。下面這篇文章主要給大家介紹了關(guān)于Python中模塊pymysql查詢結(jié)果后如何獲取字段列表的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)看看詳細(xì)的介紹。2017-06-06
python寫(xiě)入已存在的excel數(shù)據(jù)實(shí)例
下面小編就為大家分享一篇python寫(xiě)入已存在的excel數(shù)據(jù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
python flask實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了python flask實(shí)現(xiàn)分頁(yè)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
使用 Python 獲取 Linux 系統(tǒng)信息的代碼
在本文中,我們將會(huì)探索使用Python編程語(yǔ)言工具來(lái)檢索Linux系統(tǒng)各種信息,需要的朋友可以參考下2014-07-07
python登錄QQ郵箱發(fā)信的實(shí)現(xiàn)代碼
python登錄QQ郵箱發(fā)信的代碼,有需要的朋友可以參考下2013-02-02

