Python 學習 第六篇:迭代和解析

Python中的迭代是指按照元素的順序逐個調用的過程,迭代概念包括:迭代協議、可迭代對象和迭代器三個概念。html

迭代協議是指有__next__()函數的對象會前進到下一個結果,而到達系列的末尾時,則會引起StopIteration異常。爲了支持迭代協議,Python內置了兩個函數:iter()和next()函數。iter()從可迭代對象中得到一個迭代器,迭代器含有next()函數。next()函數的做用就是調用對象的__next__()函數,從而遞進進到下一項。函數

在Python中,任何支持迭代協議的對象都是可迭代的。若是對象是序列類型,或者在迭代工具中一次產生一個結果,那麼就是可迭代的,這就覺得着,序列(字符串、元組和列表)是可迭代對象。工具

迭代器是Python中實現迭代協議的對象,具體指的是iter()返回的,支持next()函數的對象。測試

Python中的迭代工具會自動調用iter()和next()函數以實現迭代,迭代工具主要有:for循環、列表解析、in成員關係測試以及map內置函數等。spa

一,手動迭代

列表不是自身的迭代器,對於這樣的可迭代對象,能夠調用iter()函數來啓動迭代,調用next()函數遞進到下一項:code

>>> a=list(range(0,5)) >>> a is iter(a) False >>> a=iter(a) >>> next(a) 0

像for循環等迭代工具,會自動調用iter()和next()函數,以實現序列的自動迭代:htm

>>> for i in range(0,5): print(i,end=' ') 0 1 2 3 4

二,生成器

生產器是一個延遲產生結果的工具,在須要的時候才產生結果,而不是當即產生結果。對象

1,生成器函數blog

Python提供了yield語句以實現生成器函數,以實如今須要的時候才產生結果,而不是當即產生結果。Python的生產器函數是指:編寫爲常規的def語句,可是使用yield語句,一次返回一個結果,在每一個結果之間掛起和繼續的狀態。 索引

生產器函數自動實現迭代協議,每次調用只返回一個值,下次調用時,會從其退出的地方繼續執行。

生產器函數和常規函數的不一樣之處在於:生產器yield一個值,而不是return一個值。yield語句掛起該函數,並向調用者發送一個值,可是,保留足夠的狀態以使得函數可以從它離開的地方繼續執行。當繼續時,函數在上一個yield返回後繼續執行。這使得生產器函數每次調用只返回一個值,窮盡調用會產生一系列的值。

>>> def seq_int(n): for i in range(n): yield i**2
    
>>> for i in seq_int(5): print(i,end =' ') 0 1 4 9 16

生產器函數返回的對象就是迭代器,可使用next()前進到下一項:

>>> func=seq_int(5) >>> iter(func) is func True >>> next(func) 0

2,生產器表達式

另一個實現生產器的對象是生產器表達式,從語法上講,生成器表達式是在小括號中的表達式。從執行過程來說,生產器表達式不在內存中構建結果,而是返回一個生成器對象,這個對象支持迭代協議。

>>> a=(x**2 for x in range(0,5)) >>> a is iter(a) True

三,解析

解析分爲列表解析,集合解析和字典解析。

  • 列表解析的格式是:[ f(x) for x in seq  ],對應的生成器表達式是:list( f(x) for x in seq )
  • 集合解析的格式是:{ f(x) for x in seq  },對應的生成器表達式是:set(f(x) for x in seq )
  • 字典解析的格式是:{key:value for (key, value) in zip(keys,values)},對應的生成器表達式是:dict((x,f(x))  for x in items  )

從語法上講,列表解析是在中括號中的表達式;從執行過程來說,列表解析對序列中的每個元素執行一個操做;從執行的結果來說,列表解析產生的一個新的列表對象。

因爲列表解析產生的結果是一個列表對象,包含全部的序列項,不屬於延遲產生結果的工具。

>>> a=[x**2 for x in range(0,5)] >>> isinstance(a,list) True

四,內置的迭代器函數

這一節,總結Python 3.0中內置的迭代器函數,除了range()函數以外,其他的函數都會產生迭代器對象,延遲產生結果。

1,range 迭代對象

range返回一個可迭代對象,該迭代對象根據須要產生範圍中的數字,而不是在內存中構建一個列表。若是須要一個範圍列表的話,必須使用list( range(...))來強制返回一個列表。

>>> r = range(0,5) >>> iter(r) is r False >>> list(r) [0, 1, 2, 3, 4] >>> r=iter(r) >>> next(r) 0

2,zip實現並行遍歷

zip()函數用於合併序列,按照序列中元素的位置,把序列的元素組合成元組,元組項的數量就是zip合併的序列的個數。當序列的長度不一樣時,zip會以最短序列的長度爲準來截斷所獲得的元組。

例如,zip把序列a和b合併爲一個序列c,c的元素的元組(0,5),(1,6),(2,7),(3,8),(4,9)。

>>> a = range(0,5) >>> b = range(5,10) >>> c = zip(a,b) >>> iter(c) is c True >>> next(c) (0, 5) >>> list(c) [(1, 6), (2, 7), (3, 8), (4, 9)]

3,map對序列應用函數

map()函數對一個序列的各個元素應用函數,返回函數調用的結果序列。

>>> m=map(ord,'abcd') >>> iter(m) is m True >>> list(m) [97, 98, 99, 100]

4,產生偏移和元素

enumerate是Python內置的函數,做用於每個序列項,獲取每個序列項偏移,並把偏移和序列項組合成元組(index, item)返回。原始序列的每一個元素及其索引都能獲得。

enumerate()函數返回一個迭代器對象,使用next()方法會返回下一個元素:

>>> t=enumerate('abcd') >>> iter(t) is t True >>> list(t) [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

在for循環結構中,每次迭代,for循環都會自動調用next()函數以返回下一個元組(index,item):

>>> [c * i for (i,c) in enumerate('abcd')]
['', 'b', 'cc', 'ddd']

5,filter迭代器

filter()函數對一個序列的各個元素應用函數,返回結果爲True的元素。

>>> f=filter(bool, ['a','','b',None]) >>> iter(f) is f True >>> list(f) ['a', 'b']

6,reduce() 函數

注意:reduce()函數並非一個迭代器,它是functools模塊中的一個工具函數。

reduce()用於對序列的元素依次應用函數,並把函數調用的結果做爲參數傳遞給函數,最終返回函數調用的結果。

>>> from functools import reduce >>> reduce((lambda x,y:x+y),range(0,5)) 10

reduce()函數執行流程等價於下面的代碼塊:

x=list(range(0,5)] res=x[0] for i in x[1:] : res+=i

 

參考文檔:

原文出處:https://www.cnblogs.com/ljhdo/p/10104824.html

相關文章
相關標籤/搜索