国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中Iterator迭代器的使用雜談

2019-11-25 16:42:53
字體:
供稿:網(wǎng)友

迭代器是一種支持next()操作的對象。它包含一組元素,當(dāng)執(zhí)行next()操作時,返回其中一個元素;當(dāng)所有元素都被返回后,生成一個StopIteration異常。

>>>a=[1,2,3]>>>ia=iter(a)>>>next(ia)1>>>next(ia)2>>>next(ia)3>>>next(ia)Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

ite()可以接受多種Python對象為參數(shù),比如list,tuple, dict, set等,并將其轉(zhuǎn)化為迭代器。迭代器可以用于for語句或in語句中。很多常用操作也是支持迭代器的,比如sum(), max()等。

>>> b=[4,5,6]>>> ib=iter(b)>>> for x in ib:...   print(x)...456>>> ic=iter(b)>>> sum(ic)15>>> id=iter(b)>>> max(ic)6

毋庸置疑,迭代器有很多好處:

1.“流式”數(shù)據(jù)處理方式減少內(nèi)存消耗:
比如處理文件,一下猛地把全部數(shù)據(jù)全部取出來放到內(nèi)存里面進(jìn)行處理會導(dǎo)致程序消耗大量內(nèi)存,有時甚至沒法做到,一般我們會一部分一部分的對文件內(nèi)容進(jìn)行處理:

for text_line in open("xx.txt"): print text_line

2.或者對xml文件進(jìn)行處理的時候:

tree = etree.iterparse(xml, ['start', 'end'])for event, elem in tree:  if event == "end"    result = etree.tostring(elem)    elem.clear()    print result

內(nèi)置函數(shù)open返回的file對象和etree.iterparse序列化的xml tree都是可迭代對象,能夠讓我們漸進(jìn)式地對文件的內(nèi)容進(jìn)行處理。

3.支持方便用for語句對數(shù)據(jù)進(jìn)行消費(fèi):
python內(nèi)置的一些常見的像類型像數(shù)組、列表甚至字符串等都是可迭代類型,這樣我們就能方便for語句這個語法糖方便對數(shù)據(jù)進(jìn)行消費(fèi),不需要自己記錄索引位置,人肉循環(huán):

for i in [1, 2, 3, 4] print i,

簡單了解了一下迭代器的好處后,我們正正經(jīng)經(jīng)的聊聊python的迭代器模式。
在這里我們引入兩個比較繞口的名詞:可迭代對象和迭代器對象,個人覺得從這兩個概念下手會對迭代器有比較好的理解。在放例子前先對這兩個概念給一個不入流的解釋:

可迭代對象:對象里面包含__iter()__方法的實(shí)現(xiàn),對象的iter函數(shù)經(jīng)調(diào)用之后會返回一個迭代器,里面包含具體數(shù)據(jù)獲取的實(shí)現(xiàn)。
迭代器:包含有next方法的實(shí)現(xiàn),在正確范圍內(nèi)返回期待的數(shù)據(jù)以及超出范圍后能夠拋出StopIteration的錯誤停止迭代。
放個例子邊看邊說:

class iterable_range:  def __init__(self, n):    self.n = n  def __iter__(self):    return my_range_iterator(self.n)class my_range_iterator:  def __init__(self, n):    self.i = 0    self.n = n  def next(self):    if self.i < self.n:      i = self.i      self.i += 1      print 'iterator get number:', i      return i    else:      raise StopIteration()

例子中的iterable_range是一個可迭代對象,所以我們也能夠?qū)λ胒or語句來進(jìn)行迭代:

temp = my_range(10)for item in temp:  print item,

輸出:

  my iterator get number: 0  0  my iterator get number: 1  1  my iterator get number: 2  2  my iterator get number: 3  3  my iterator get number: 4  4  my iterator get number: 5  5  my iterator get number: 6  6  my iterator get number: 7  7  my iterator get number: 8  8  my iterator get number: 9  9

大家可以仔細(xì)地看一下輸出的日志:

  • 數(shù)據(jù)確實(shí)是“流式”處理的
  • iterator是真正在背后做事的人
  • for語句能夠非常方便的迭代對象的數(shù)據(jù)。

可迭代對象其實(shí)更像是整個迭代器模式模式的上層,像一種約束一種契約一種規(guī)范,它能夠保證自己能夠返回一個在實(shí)際工作中干活的迭代器對象。for、sum等接受一個可迭代對象的方法都是遵循這樣的規(guī)范:調(diào)用對象的__iter__函數(shù),返回迭代器,對迭代器對象返回的每個值進(jìn)行處理抑或需要一些匯總的操作。拿for舉個例子:

iterator_object = iterable_object.__iter__()while True:  try:    value = iterator_object.next()  except StopIteration:    # StopIteration exception is raised after last element    break  # loop code  print value

for這個語法糖背后的邏輯差不多就是上面例子中代碼所示的那樣:首先獲取可迭代對象返回的迭代器對象,然后調(diào)用迭代器對象的next方法獲取每個值,在獲取值的過程中隨時檢測邊界-也就是檢查是否拋出了StopIteration這樣的錯誤,如果迭代器對象拋出錯誤則迭代停止(note:從這個例子可以看出,對于那些接受可迭代對象的方法,如果我們傳一個單純的迭代器對象其實(shí)也是無法工作的,可能會報(bào)出類似于TypeError: iteration over non-sequence的錯誤)。
當(dāng)然了,一般在應(yīng)用過程中我們不會將他們特意的分開,我們能夠稍微對迭代器對象進(jìn)行修改一下,添加__iter__方法的實(shí)現(xiàn),這樣對象本身就既是可迭代對象也是一個迭代器對象了:

class my_range_iterator:   def __init__(self, n):    self.i = 0    self.n = n   def __iter__(self):    return self   def next(self):    if self.i < self.n:      i = self.i      self.i += 1      print 'my iterator get number:', i      return i    else:      raise StopIteration() for item in my_range_iterator(10):   print item

輸出:

 

  my iterator get number: 0  0  my iterator get number: 1  1  my iterator get number: 2  2  my iterator get number: 3  3  my iterator get number: 4  4  my iterator get number: 5  5  my iterator get number: 6  6  my iterator get number: 7  7  my iterator get number: 8  8  my iterator get number: 9  9

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 柳河县| 如东县| 绿春县| 长春市| 隆化县| 晋中市| 鄂伦春自治旗| 太湖县| 凤阳县| 宜川县| 林口县| 安阳市| 永善县| 黄龙县| 宁晋县| 梁山县| 青浦区| 南开区| 灯塔市| 阿拉善盟| 乌拉特中旗| 丰原市| 巴南区| 崇礼县| 新巴尔虎左旗| 江达县| 宁化县| 昌都县| 棋牌| 高尔夫| 和田县| 南京市| 塘沽区| 万荣县| 通州区| 平顶山市| 青冈县| 吴川市| 深泽县| 昌平区| 张家川|