python筆記 迭代器

2021-10-06 11:28:55 字數 4757 閱讀 8902

?能被next()函式呼叫,並不斷返回下乙個值的物件稱為迭代器(iterator 迭代器物件),迭代器是訪問集合元素的一種方式,是python中最具特色的功能之一。

?迭代器可以記住訪問遍歷的位置,從集合的第乙個元素開始訪問,直到集合中的所有元素被訪問完畢。迭代器只能從前往後乙個乙個的遍歷,不能後退。

?迭代器的優勢在於支援自身遍歷,同時,它的特點是單向非迴圈的,一旦完成遍歷,再次呼叫就會報錯。

比如:普通可迭代物件就像是子彈匣,它遍歷就是取出子彈,在完成操作後又裝回去,所以可以反覆遍歷(即多次呼叫for迴圈,返回相同結果);而迭代器就像是裝載了子彈匣而不可拆卸的槍,進行它遍歷或自遍歷都是發射子彈,這是消耗性的遍歷,是無法復用的(即遍歷會有盡頭)。

1.相關函式

iter()

功能: 把可迭代的物件轉為乙個迭代器物件          

引數: 可迭代的物件 (str,list,tuple,dict)

返回值:迭代器物件

next()

2.迭代器取值

特點:取出乙個少乙個,直到都取完,最後再取就會報錯

迭代器取值方案:

1. next() 呼叫一次獲取一次,直到資料被取完                   

2. list() 使用list函式直接取出迭代器中的所有資料

3. for 使用for迴圈遍歷迭代器的資料

舉例:

# 定義乙個列表,是乙個可迭代的物件

f4 =

['趙四'

,'劉能'

,'小瀋陽'

,'海參炒麵'

] res =

iter

(f4)

# 把可迭代物件轉為迭代器使用 iter()

print

(res,

type

(res))#

# 1.使用next()函式去呼叫迭代器物件

print

(next

(res)

)#趙四

print

(next

(res)

)#劉能

#2.使用list取值

r =list

(res)

print

(r)#直接執行2,返回['趙四', '劉能', '小瀋陽', '海參炒麵']

#執行完1再執行2,返回['小瀋陽', '海參炒麵']

#3.使用for迴圈

for i in res:

print

(i)#直接執行3,返回:

'''趙四

劉能小瀋陽

海參炒麵

'''# print(next(res)) #報錯:stopiteration, 即超出可迭代的範圍

3.檢測迭代器和可迭代物件的方法

迭代器一定是乙個可迭代的物件,可迭代物件不一定是迭代器

迭代是一種遍歷元素的方式,按照實現方式劃分,有外部迭代與內部迭代兩種,支援外部迭代(它遍歷)的物件就是可迭代物件,而同時還支援內部迭代(自遍歷)的物件就是迭代器;按照消費方式劃分,可分為復用型迭代與一次性迭代,普通可迭代物件是復用型的,而迭代器是一次性的。

from collections.abc import iterator,iterable
varstr =

'123456'

#可迭代物件

res =

iter

(varstr)

#可迭代物件+迭代器

r1 =

isinstance

(varstr,iterable)

# true 可迭代物件

r2 =

isinstance

(varstr,iterator)

# false 不是乙個迭代器

r3 =

isinstance

(res,iterable)

# true 可迭代物件

r4 =

isinstance

(res,iterator)

# true 是乙個迭代器

print

(r1,r2)

print

(r3,r4)

type() 函式返回當前資料的型別,                                           

isinstance() 檢測乙個資料是不是乙個指定的型別

4.迭代器切片
itertools模組的 islice()方法將迭代器與切片完美結合

為了更直觀地感受迭代器內部的執行過程,我們自定義乙個迭代器,以斐波那契數列為例:

from itertools import islice

class

fib:

def__init__

(self)

: self.prev =

0 self.curr =

1def

__iter__

(self)

:return self

def__next__

(self)

: value = self.curr

self.curr += self.prev

self.prev = value

return value

f = fib(

)print

(list

(islice(f,0,

10)))

#返回[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

fib既是乙個可迭代物件(因為它實現了 __iter__方法),又是乙個迭代器(因為實現了 __next__方法)。

例項變數prev和curr使用者維護迭代器內部的狀態。

每次呼叫 next()方法的時候做兩件事:

迭代器就像乙個懶載入的工廠,等到有人需要的時候才給它生成值返回,沒呼叫的時候就處於休眠狀態等待下一次呼叫。

itertools 模組的切片方法的實現邏輯參看下方官網提供的原始碼:

def

islice

(iterable,

*args)

:# islice('abcdefg', 2) --> a b

# islice('abcdefg', 2, 4) --> c d

# islice('abcdefg', 2, none) --> c d e f g

# islice('abcdefg', 0, none, 2) --> a c e g

s =slice

(*args)

# 索引區間是[0,sys.maxsize],預設步長是1

start, stop, step = s.start or

0, s.stop or sys.maxsize, s.step or

1 it =

iter

(range

(start, stop, step)

)try

: nexti =

next

(it)

except stopiteration:

# consume *iterable* up to the *start* position.

for i, element in

zip(

range

(start)

, iterable)

:pass

return

try:

for i, element in

enumerate

(iterable)

:if i == nexti:

yield element

nexti =

next

(it)

except stopiteration:

# consume to *stop*.

for i, element in

zip(

range

(i +

1, stop)

, iterable)

:pass

islice() 方法的索引方向是受限的,但它也提供了一種可能性:即允許你對乙個無窮的(在系統支援範圍內)迭代器進行切片的能力。這是迭代器切片最具想象力的用途場景。

5.小結

迭代器是一種特殊的可迭代物件,可用於它遍歷與自遍歷,但遍歷過程是損耗型的,不具備迴圈復用性,因此,迭代器本身不支援切片操作;通過借助 itertools 模組,我們能實現迭代器切片,將兩者的優勢相結合,其主要用途在於擷取大型迭代器(如無限數列、超大檔案等等)的片段,實現精準的處理,從而大大地提公升效能與效率。

python 迭代器 筆記

1.凡事可用於for迴圈的物件都是iterable型別物件 2.凡事可做用於next 函式的物件都是iterator型別物件,他們表示乙個惰性計算的序列 3.集合資料型別list dicr str等是iterable物件不是iterator物件,但是可以通過呼叫iter 函式獲得乙個iterator...

Python筆記 迭代器

我們已經知道,可以直接作用於for迴圈的資料型別有以下幾種 一類是集合資料型別,如list tuple dict set str等 一類是generator,包括生成器和帶yield的generator function。這些可以直接作用於for迴圈的物件統稱為可迭代物件 iterable。1 可以...

python迭代器筆記

迭代器的優點 迭代器訪問與for迴圈訪問非常相似,但是也有不同之處。對於支援隨機訪問的資料結構如元組和列表,迭代器並無優勢。因為迭代器在訪問的時候會丟失資料索引值,但是如果遇到無法隨機訪問的資料結構如集合時,迭代器是唯一訪問元素的方式 迭代器僅僅在訪問到某個元素時才使用該元素。在這之前,元素可以不存...