Python迭代器與生成器
列表生成式
列表生成式也叫做列表推導(dǎo)式,它本身還是列表,只不過(guò)它是根據(jù)我們定義的規(guī)則來(lái)生成一個(gè)真實(shí)的列表。
list2 = [x for x in range(10)] print(list2)
下面是一個(gè)復(fù)雜的列子:
list1 = [x * y for x in range(1, 5) if x > 2 for y in range(1, 4) if y < 3] # 上面的列表生成式等同于下面的代碼 list4 = [] for x in range(1, 5): if x > 2: for y in range(1, 4): if y < 3: list4.append(x * y)
生成器
如果要?jiǎng)?chuàng)建一個(gè)100萬(wàn)個(gè)元素的列表,你使用上面的方式無(wú)疑非常占用內(nèi)存,這時(shí)候就用到了生成器,它其實(shí)是保存一個(gè)你定義的規(guī)則,在需要用到元素的時(shí)候按照規(guī)則去生成一個(gè),而不是保存好一大堆元素,這樣就減少內(nèi)存占用。不過(guò)生成器的元素只能順序依次獲取不能像真正列表那樣可以按位置獲取而且不能回退。
創(chuàng)建一個(gè)生成器,生成器保存的是一個(gè)算法,而不是具體的內(nèi)容。可以看到和列表生成式的區(qū)別是就是把[]換成(),generator = (x for x in range(10))。
其實(shí)生成器就是一個(gè)迭代器,只不過(guò)它是一種特殊的迭代器:
print("generator是否是迭代器:", isinstance(generator, Iterator)) # 結(jié)果為 True print("generator是否是可迭代對(duì)象:", isinstance(generator, Iterable)) # 結(jié)果為 True
如果要想獲取生成器元素就只能通過(guò)next來(lái)獲取下一個(gè)元素,必須順序獲取,當(dāng)沒(méi)有元素的時(shí)候拋出 StopIteration 異常。print(generator.__next__()) # 也可以這樣來(lái)使用 next(generator)。
用生成器實(shí)現(xiàn)斐波那契數(shù)列:
def fib(length): """ 生成器定義一個(gè)斐波那契數(shù)列,生成器本身就是yield + next實(shí)現(xiàn)。外部調(diào)用next來(lái)觸發(fā)一次計(jì)算 函數(shù)遇到y(tǒng)ield返回,然后下一次next則繼續(xù)從上一次yield的地方向下執(zhí)行,直到遇到某個(gè)結(jié)束條件 :param length: """ n, a, b = 0, 0, 1 while n < length: yield b """ a, b = b, a + b 等于 t = (b, a + b) a=t[0] b=t[1] 當(dāng)計(jì)算b = a + b的時(shí)候, 這里的a并不是之前 a = b 之后a值,而是之前的a值,所以它是先做 = 右邊的計(jì)算,然后賦值給左邊的 """ a, b = b, a + b n = n + 1 return 'done' for i in fib(10): print(i)
迭代器
可以用next()函數(shù)調(diào)用來(lái)獲取下一個(gè)元素的對(duì)象叫做迭代器。生成器就可以,但是普通集合類比如list、dict、str就不可以。集合類的對(duì)象比如list、dict、set、str;還有生成器都是可迭代對(duì)象,也就是可以遍歷的。但是它們并不一定都是迭代器。list、dict、str等數(shù)據(jù)類型不是Iterator。
list1 = [1, 2, 3, 4, 5, 6] print("list1是否是迭代器:", isinstance(list1, Iterator)) # 結(jié)果為 False print("list1是否是可迭代對(duì)象:", isinstance(list1, Iterable)) # 結(jié)果為 True print("list1的長(zhǎng)度:", len(list1)) # 結(jié)果為具體長(zhǎng)度 if hasattr(list1, "__next__"): print("list1是迭代器")
把list1變成迭代器:
interObj = iter(list1) print("list1是否是迭代器:", isinstance(interObj, Iterator)) # 結(jié)果為 True print("list1是否是可迭代對(duì)象:", isinstance(interObj, Iterable)) # 結(jié)果為 False # print("interObj的長(zhǎng)度:", len(interObj)) # 無(wú)法獲取長(zhǎng)度 if hasattr(interObj, "__next__"): print("interObj是迭代器")
可遍歷的對(duì)象不一定是迭代器,但是肯定是可迭代對(duì)象。
迭代器同時(shí)一定也是可迭代對(duì)象。生成器是一種特殊的迭代器,所以也是可迭代對(duì)象。
可迭代對(duì)象和迭代器最大的區(qū)別就是前者可以通過(guò)len()獲取長(zhǎng)度而后者不能
且迭代器一定可以通過(guò)next()函數(shù)(說(shuō)明該對(duì)象包含__next__內(nèi)置方法)獲取下一個(gè)元素,而可迭代對(duì)象不一定。
-
生成器
+關(guān)注
關(guān)注
7文章
321瀏覽量
21195 -
python
+關(guān)注
關(guān)注
56文章
4812瀏覽量
85146 -
迭代器
+關(guān)注
關(guān)注
0文章
45瀏覽量
4360
原文標(biāo)題:Python迭代器與生成器
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
STM32庫(kù)函數(shù)代碼自動(dòng)生成器正式版
了解Python數(shù)據(jù)結(jié)構(gòu)迭代對(duì)象、迭代器、生成器的概念

評(píng)論