python進階(小白也能看懂)——生成器與迭代器

python進階(小白也能看懂)——生成器與迭代器

第二篇

1 例子

先給出生成器與迭代器的例子,然後詳細講解需要理解的知識。

1.1 生成器

# 生成器
a = (i+1 for i in range(10))
# 列表推導式,不是生成器
b = [i+1 for i in range(10)]
# 生成器
def generator(n):
	z = 1
	while z<n:
		z += 1
		yield z
	return "done"
c = generator(5)
# 如果不信可以使用print驗證
print(a,b,c,sep="\n")

輸出結果

<generator object <genexpr> at 0x000001D1B1E48570>
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
<generator object generator at 0x000001D1B2E8A138>

1.2 迭代器

# 迭代器
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    # 返回迭代器對象本身
    def __iter__(self):
        return self

    # 返回容器下一個元素
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a
d = Fib()
# 判斷d是否爲迭代器
isinstance(d, Iterator)

輸出結果

True

2 什麼是生成器與迭代器

在 Python 中,迭代器是指遵循迭代器協議(iterator protocol)的對象。
迭代器協議:任意對象只要定義了__iter__方法和__next__方法就是迭代器,就像上面例子給出的一樣。

再說明一下與迭代器相關的名詞:迭代與可迭代對象

迭代(Iteration):當我們用一個循環(比如 for 循環)來遍歷容器(比如列表,元組)中的元素時,這種遍歷的過程就叫迭代。

可迭代對象(Iterable):直觀上可以用for循環遍歷的對象就是可迭代對象。 嚴格地定義說,Python中任意的對象,只要它定義了可以返回⼀個迭代器的__iter__⽅法,或者定義了可以⽀持下標索引的__getitem__⽅法,那麼它就是⼀個可迭代對象。

2.1 迭代器與可迭代對象的區別

相同點:都可以使用for循環取出元素。
不同點:迭代器一定是可迭代對象,但可迭代對象不一定是迭代器。迭代器可以使用python內置的next方法一個一個取出元素,而可迭代對象不行。(從上面的定義也可以看出,因爲可迭代對象沒有實現__next__方法)

iterator = (i+1 for i in range(5)) # 迭代器
iterable = [i+1 for i in range(5)] # 可迭代對象

# 判斷itrable爲可迭代對象
from collections import Iterable
isinstance(iterator, Iterable) # True
isinstance(iterable, Iterable) # True 
hasattr(iterable,'__iter__')   # True 
hasattr(iterable,'__getitem__' # True

# 判斷iterator是否爲迭代器
from collections import Iterator
isinstance(iterator, Iterator) # True
isinstance(iterable, Iterator) # False 

# iterator可以使用next方法
next(iterator) # 1
# iterable不能使用next方法
next(iterable) # 'list' object is not an iterator

2.2 爲什麼使用迭代器

與列表不同,迭代器不會把元素一次性加載到內存,而是以延遲方式加載。如列表中含有一千萬個整數,需要佔超過400M的內存,而迭代器只需要幾十個字節的空間。因爲它並沒有把所有元素裝載到內存中,而是等到調用 next 方法時候才返回該元素。這樣就不會消耗大量資源。(在使用for循環迭代的過程中,本質上是調用迭代器的next方法取出元素)

2.3 生成器——一種特殊的迭代器

生成器(generator)也是一種迭代器,它有和迭代器一樣的特性,唯一的區別在於生成器的構造方式更加簡潔。它通常採用yield將函數構造生成器或者使用生成器表達式()構造生成器。具體如何構造可以參考1.1 生成器的例子

3 參考

極客學院——生成器
極客學院——迭代器
生成器與迭代器

發佈了84 篇原創文章 · 獲贊 113 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章