Python迭代器和生成器

2021-09-24 15:35:44 字數 3099 閱讀 4068

在python中,迭代(iteration)的概念是建立在容器的基礎上的,所有的容器都是可迭代的(iterable)。容器是物件的集合,列表、元組、字典、集合等都是容器。不同容器之間的區別在於內部資料結構的實現方式不同。可迭代物件(列表、元組、字典、集合等)通過iter(iterable)函式返回乙個迭代器,next(iterator)函式可實現在迭代器中遍歷。next(iterator)函式要麼返回當前物件的下乙個物件,要麼丟擲stopiteration的錯誤。

container =[[

1,2,

3,4]

,(1,

2,3,

4),set([

1,2,

3,4]

),,'abcd'

]for it in container:

it =

iter

(it)

print

(it)

while

true

:try

:print

(next

(it)

)except stopiteration:

break

# 輸出

# # 1 2 3 4

# # 1 2 3 4

# # 1 2 3 4

# # 1 2

# # a b c d

生成器實質上也是乙個迭代器,只不過在迭代器中的資料都是已經存在的,而生成器是在需要資料時才臨時生成資料。相比於迭代器,這樣的特性有利於節省記憶體空間。

例如,[i for i in range(1000000)]生成乙個包含一百萬元素的列表,每個元素都存在於記憶體中,佔據了大量的空間。但是我們有時候並不需要在記憶體同時儲存這些元素,例如對列表中的所有元素求和,我們每次只需要知道下乙個元素的值並對其進行累加,累加完後即可丟棄,然後依次迭代下去,就可以求出所有元素的和。 生成器的寫法如下,和迭代器相比,只不過把中括號換成了小括號。

iterator =

[i for i in

range

(1000000)]

# 迭代器

generator =

(i for i in

range

(1000000))

# 生成器

下面是兩個生成器的例子,在python中,帶有yield關鍵字的函式稱為生成器。當呼叫生成器時,每次遇到yield時函式會暫停並儲存當前位置的資訊,然後返回yield當前值。在下次執行next()時從之前儲存的位置繼續執行。

def

generator

(n):

i =1while i < n:

yield i

i +=

1g = generator(10)

print

(g)while

true

:try

:print

(next

(g))

except stopiteration:

break

# 輸出

# # 1 2 3 4 5 6 7 8 9 10

def

generator

(s, l)

:for i, v in

enumerate

(s):

if v == l:

yield i

g = generator(

,'e'

)while

true

:try

:print

(next

(g))

except stopiteration:

break

# 輸出

# 5 10

現在有乙個判斷子串行的問題。如果第乙個列表中的元素在第二個列表中依次出現,則第乙個列表就是第二個列表的子串行。例如[1, 3, 5]是[1, 2, 3, 4, 5]的子串行,[1, 5, 3]不是[1, 2, 3, 4, 5]的子串行。

常規的解法是通過兩個指標分別指向兩個列表的開端,然後遍歷第二個列表。當兩個指標指向的元素相同時,就把第乙個指標向後移動一位,直到指標指向最後乙個元素的下一位時,返回true,否則返回false。

def

issubsequence

(s, t)

: p =

0for i in

range

(len

(t))

:if t[i]

== s[p]

: p +=

1if p ==

len(s)

:return

true

return

false

如果利用生成器來解,則只需要兩行。

def

is_subsequence

(s, t)

: t =

iter

(t)return

all(i in t for i in s)

首先通過t = iter(t)將t轉化為乙個迭代器,然後對s中的每個元素,依次判斷該元素是否在t中。all()表示括號中的所有元素為true時才返回true。

這裡i in t是**的關鍵。表示依次遍歷t中的元素,如果某個元素等於i,則返回true,否則遍歷結束後返回false。如果遍歷結束前某個元素等於i,則中斷遍歷,返回true。當第二次執行這條語句時(即判斷下個元素是否在t中),將直接從上次遍歷中斷的位置繼續執行。也就是說生成器只能遍歷一次,且不可逆。當遍歷中斷時,下次繼續遍歷只會從上次中斷的位置開始,而不會從頭開始。可以驗證一下:

t =[1

,2,3

,4,5

]t =

iter

(t)print(2

in t)

print(4

in t)

print(3

in t)

# 輸出

# true

# true

# false

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 迭代器和生成器

迭代器是訪問集合元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退,不過這也沒什麼,因為人們很少在迭代途中往後退。另外,迭代器的一大優點是不要求事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代到某個元素時才計算該元素,而在這之前或之後,元素可...