一個對象實現了__iter__()方法,就是可迭代對象。咱們經過兩種方法判斷str、tuple、range、list、set、dict類型的容器是否爲可迭代對象。一種方法是經過dir()函數查看目標對象是否具備__iter__()方法;另外一種方法是從collections模塊中導入Iterable屬性,利用isinstance()函數判斷目標對象是否爲Iterable類型,若是是的話,該目標對象即爲可迭代對象。python
s = 'my name is david' #str類型 t = (1,2,3,'a','5') #tuple類型 r = range(10) #range類型 l = [1,2,3,4,5] #list類型 st = {'a','b','c',4,5} #set類型 d = {'a':1,'b':2,'c':3,'d':4} #dict類型 from collections import Iterable #使用Iterable屬性判斷目標對象是否爲可迭代對象 print(isinstance(s,Iterable)) print(isinstance(t,Iterable)) print(isinstance(r,Iterable)) print(isinstance(l,Iterable)) print(isinstance(st,Iterable)) print(isinstance(d,Iterable))
一個對象同時實現了__iter__()方法與__next__()方法,就是迭代器。爲了更直觀地感覺迭代器,咱們自定義一個斐波那契數列類Fib,將該類實例化以後能夠生成迭代器。socket
class Fib: def __init__(self): self.prev = 0 self.curr = 1 def __iter__(self): #一個對象實現__iter__()方法,就是可迭代對象。 return self def __next__(self): #一個可迭代對象實現__next__()方法,就是迭代器。 value = self.curr self.curr += self.prev self.prev = value return value f = Fib() from collections import Iterable, Iterator print(isinstance(f,Iterable)) #f既是可迭代對象 print(isinstance(f,Iterator)) #f也是迭代器
在這裏,咱們經過創建一個Fib類,而後實例化爲一個f對象的形式自定義一個迭代器。能夠說自定義迭代器的方式是比較笨拙的,後面咱們會介紹生成器,與迭代器相比,自定義生成器是比較簡潔、優雅的。函數
迭代器不會一次性將全部的元素都加載到內存,等到使用next()調用的時候纔給它生成值返回,沒調用的時候就處於休眠狀態等待下一次調用。itertools模塊中的函數返回的都是迭代器對象。工具
from collections import Iterator from itertools import count counter = count(start=13) print(isinstance(counter,Iterator)) from itertools import cycle colors = cycle(['red','yellow','blue']) print(isinstance(colors,Iterator)) from itertools import islice iterslice = islice(counter,2,12) print(isinstance(iterslice,Iterator))
使用python內置函數iter()能夠將可迭代對象變成迭代器。code
from collections import Iterator s = 'my name is david' #str類型 t = (1,2,3,'a','5') #tuple類型 r = range(10) #range類型 l = [1,2,3,4,5] #list類型 st = {'a','b','c',4,5} #set類型 d = {'a':1,'b':2,'c':3,'d':4} #dict類型 si = iter(s) print(isinstance(si,Iterator)) ti = iter(t) print(isinstance(ti,Iterator)) ri = iter(r) print(isinstance(ri,Iterator)) li = iter(l) print(isinstance(li,Iterator)) sti = iter(st) print(isinstance(sti,Iterator)) di = iter(d) print(isinstance(di,Iterator))
Python 3中關於iter(object[, sentinel])方法有兩個參數。 使用iter(object)這種形式比較常見。 iter(object, sentinel)這種形式通常較少使用,Python的文檔說明貌似也不容易理解。對象
生成器(generator)是一種特殊的迭代器,與迭代器相比,生成器更爲優雅。它不須要再像上面的類同樣寫__iter__()和__next__()方法,只須要一個yiled關鍵字,像定義函數同樣自定義生成器。咱們建立了一個生成器後,基本上永遠不會調用next()方法,而是經過for循環來迭代它。 與自定義迭代器相比,下面這種使用生成器來建立斐波那契數列的方式是否是更優雅?內存
def fib(): prev, curr = 0, 1 while True: yield curr prev, curr = curr, curr + prev f = fib() #建立迭代器 from itertools import islice #導入迭代器切片工具 list(islice(f,0,10))
此外,咱們還可使用生成器表達式來構造生成器。與列表生成式相似,只須要把一個列表生成式的[]改爲(),就能夠建立一個生成器。文檔
>>> l = [x*x for x in range(10)] >>> l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x*x for x in range(10)) >>> g <generator object <genexpr> at 0x0000026428DEC308>