python可迭代對象 迭代器生成器_Python可迭代對象、迭代器和生成器

8.1 可迭代對象(Iterable)

大部分對象都是可迭代,只要實現了__iter__方法的對象就是可迭代的。

__iter__方法會返回迭代器(iterator)本身,例如:

>>> lst = [1,2,3]

>>> lst.__iter__()

Python提供一些語句和關鍵字用于訪問可迭代對象的元素,比如for循環、列表解析、邏輯操作符等。

判斷一個對象是否是可迭代對象:

>>> from collections import Iterable ?# 只導入Iterable方法

>>> isinstance('abc', Iterable)

True

>>> isinstance(1, Iterable)

False

>>> isinstance([], Iterable)

True

這里的isinstance()函數用于判斷對象類型,后面會講到。

可迭代對象一般都用for循環遍歷元素,也就是能用for循環的對象都可稱為可迭代對象。

例如,遍歷列表:

>>>?lst =?[1, 2, 3]

>>> for i in lst:

...? ?print i

...

1

2

3

博客地址:http://lizhenliang.blog.51cto.com and https://yq.aliyun.com/u/lizhenliang

QQ群:323779636(Shell/Python運維開發群)

8.2 迭代器(Iterator)

具有next方法的對象都是迭代器。在調用next方法時,迭代器會返回它的下一個值。如果next方法被調用,但迭代器沒有值可以返回,就會引發一個StopIteration異常。

使用迭代器的好處:

1)如果使用列表,計算值時會一次獲取所有值,那么就會占用更多的內存。而迭代器則是一個接一個計算。

2)使代碼更通用、更簡單。

8.2.1 迭代器規則

回憶下在Python數據類型章節講解到字典迭代器方法,來舉例說明下迭代器規則:

>>> d = {'a':1, 'b':2, 'c':3}

>>> d.iteritems()

# 判斷是否是迭代器

>>> from collections import Iterator

>>> isinstance(d, Iterator)

False

>>> isinstance(d.iteritems(), Iterator)

True

# 使用next方法。

>>> iter_items = d.iteritems()

>>> iter_items.next()

('a', 1)

>>> iter_items.next()

('c', 3)

>>> iter_items.next()

('b', 2)

由于字典是無序的,所以顯示的是無序的,實際是按照順序獲取的下一個元素。

8.2.2 iter()函數

使用iter()函數轉換成迭代器:

語法:

iter(collection) -> iterator

iter(callable, sentinel) -> iterator

>>> lst =?[1, 2, 3]

>>> isinstance(lst, Iterator)

False

>>> lst.next() ?# 不是迭代器是不具備next()屬性的

Traceback (most recent call last):

File "", line 1, in

AttributeError: 'list' object has no attribute 'next'

>>> iter_lst = iter(lst)

>>> isinstance(iter_lst, Iterator)

True

>>> iter_lst.next()

1

>>> iter_lst.next()

2

>>> iter_lst.next()

3

8.2.3 itertools模塊

itertools模塊是Python內建模塊,提供可操作迭代對象的函數。可以生成迭代器,也可以生成無限的序列迭代器。

有下面幾種生成無限序列的方法:

count([n]) --> n, n+1, n+2, ...

cycle(p) --> p0, p1, ... plast, p0, p1, ...

repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times

也有幾個操作迭代器的方法:

islice(seq, [start,] stop [, step]) --> elements from

chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...

groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)

imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...

ifilter(pred, seq) --> elements of seq where pred(elem) is True

1)count生成序列迭代器

>>> from itertools import *? # 導入所有方法

# 用法 count(start=0, step=1) --> count object

>>> counter = count()

>>> counter.next()

0

>>> counter.next()

1

>>> counter.next()

2

......

可以使用start參數設置開始值,step設置步長。

2)cycle用可迭代對象生成迭代器

# 用法 cycle(iterable) --> cycle object

>>> i = cycle(['a', 'b', 'c'])

>>> i.next()

'a'

>>> i.next()

'b'

>>> i.next()

'c'

3)repeat用對象生成迭代器

# 用法 repeat(object [,times]) -> create an iterator which returns the object,就是任意對象

>>> i = repeat(1)

>>> i.next()

1

>>> i.next()

1

>>> i.next()

1

......

可使用無限次。

也可以指定次數:

>>> i = repeat(1, 2)

>>> i.next()

1

>>> i.next()

1

>>> i.next()

Traceback (most recent call last):

File "", line 1, in

StopIteration

4)islice用可迭代對象并設置結束位置

# 用法 islice(iterable, [start,] stop [, step]) --> islice object

>>> i = islice([1,2,3],2)

>>> i.next()

1

>>> i.next()

2

>>> i.next()

Traceback (most recent call last):

File "", line 1, in

StopIteration

正常的話也可以獲取的3。

5)chain用多個可迭代對象生成迭代器

# 用法 chain(*iterables) --> chain object

>>> i = chain('a','b','c')

>>> i.next()

'a'

>>> i.next()

'b'

>>> i.next()

'c'

6)groupby將可迭代對象中重復的元素挑出來放到一個迭代器中

# 用法 groupby(iterable[, keyfunc]) -> create an iterator which returns

>>> for key,group in groupby('abcddCca'):

...? ?print key,list(group)

...

a ['a']

b ['b']

c ['c']

d ['d', 'd']

C ['C']

c ['c']

a ['a']

groupby方法是區分大小寫的,如果想把大小寫的都放到一個迭代器中,可以定義函數處理下:

>>> for key,group in groupby('abcddCca', lambda c: c.upper()):

...? ?print key, list(group)

...

A ['a']

B ['b']

C ['c']

D ['d', 'd']

C ['C', 'c']

A ['a']

7)imap用函數處理多個可迭代對象

# 用法 imap(func, *iterables) --> imap object

>>> a = imap(lambda x, y: x * y,[1,2,3],[4,5,6])

>>> a.next()

4

>>> a.next()

10

>>> a.next()

18

8)ifilter過濾序列

# 用法 ifilter(function or None, sequence) --> ifilter object

>>> i = ifilter(lambda x: x%2==0,[1,2,3,4,5])

>>> for i in i:

...? ?print i

...

2

4

當使用for語句遍歷迭代器時,步驟大致這樣的,先調用迭代器對象的__iter__方法獲取迭代器對象,再調用對象的__next__()方法獲取下一個元素。最后引發StopIteration異常結束循環。

8.3 生成器(Generator)

什么是生成器?

1)任何包含yield語句的函數都稱為生成器。

2)生成器都是一個迭代器,但迭代器不一定是生成器。

8.3.1 生成器函數

在函數定義中使用yield語句就創建了一個生成器函數,而不是普通的函數。

當調用生成器函數時,每次執行到yield語句,生成器的狀態將被凍結起來,并將結果返回__next__調用者。凍結意思是局部的狀態都會被保存起來,包括局部變量綁定、指令指針。確保下一次調用時能從上一次的狀態繼續。

以生成斐波那契數列舉例說明yield使用:

斐波那契(Fibonacci)數列是一個簡單的遞歸數列,任意一個數都可以由前兩個數相加得到。

#!/usr/bin/python

# -*- coding: utf-8 -*-

def fab(max):

n, a, b = 0, 0, 1

while n < max:

print b

a, b = b, a + b

n += 1

fab(5)

# python test.py

1

1

2

3

5

使用yied語句,只需要把print b改成yield b即可:

#!/usr/bin/python

# -*- coding: utf-8 -*-

def fab(max):

n, a, b = 0, 0, 1

while n < max:

yield b

# print b

a, b = b, a + b

n += 1

print fab(5)

# python test.py

可見,調用fab函數不會執行fab函數,而是直接返回了一個生成器對象,上面說過生成器就是一個迭代器。那么就可以通過next方法來返回它下一個值。

>>> import test

>>> f = test.fab(5)

>>> f.next()

1

>>> f.next()

1

>>> f.next()

2

>>> f.next()

3

>>> f.next()

5

每次fab函數的next方法,就會執行fab函數,執行到yield b時,fab函數返回一個值,下一次執行next方法時,代碼從yield b的嚇一跳語句繼續執行,直到再遇到yield。

8.3.2 生成器表達式

在第四章 Python運算符和流程控制章節講過,簡化for和if語句,使用小括號()返回一個生成器,中括號[]生成一個列表。

回顧下:

# 生成器表達式

>>> result = (x for x in range(5))

>>> result

at 0x030A4FD0>

>>> type(result)

# 列表解析表達式

>>> result = [ x for x in range(5)]

>>> type(result)

>>> result

[0, 1, 2, 3, 4]

第一個就是生成器表達式,返回的是一個生成器,就可以使用next方法,來獲取下一個元素:

>>> result.next()

0

>>> result.next()

1

>>> result.next()

2

......

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276427.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276427.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276427.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows Mobile下使用CppUnitLite輸出測試結果

背景 TDD測試驅動開發是當前流行的開發方法及模式。遵循TDD的方法對開發程序庫(Library)特別有用&#xff0c;因為Library就是為第三方提供一定功能接口的實現&#xff0c;使用TDD的方法可以預先為定義的接口提供測試案例&#xff0c;保證實現代碼能通過測試&#xff0c;保證Li…

sql注意事項2點

①對Null的判斷,如果要用<>與null判斷,則都會得到否定結果②insert into時,要把字段顯示指出,不然會因字段位置變化出錯③-一個數時,如果有可能存在Null,則結果會被置為Null解決方法,select出來的結果,最好加isnull判斷轉載于:https://www.cnblogs.com/lishenglyx/archiv…

PHP IE中下載附件問題

重點&#xff1a; 1、在IE中下載附件之前要清空緩存。 2、中文文件名要用urlencode編碼。 Header("Pragma: "); //不加的話&#xff0c;IE中會提示目標主機無法訪問 Header("Cache-Control: "); //不加的話&#xff0c;IE中會提示目標…

10 個你可能還不知道 VS Code 使用技巧

經常幫一些同學 One-on-One 地解決問題&#xff0c;在看部分同學使用 VS Code 的時候&#xff0c;有些蹩腳&#xff0c;實際上一些有用的技巧能夠提高我們的日常工作效率。NO.1一、重構代碼VS Code 提供了一些快速重構代碼的操作&#xff0c;例如&#xff1a;將一整段代碼提取為…

使用MAP文件快速定位程序崩潰代碼行(轉)

作為程序員&#xff0c;平時最擔心見到的事情就是程序發生了崩潰&#xff0c;無論是指針越界還是非法操作&#xff0c;都將給我們的應用系統造成巨大的損失。但在一個大型系統的測試過程中&#xff0c;初期出現程序崩潰似乎成了不可避免的事。其實測試中出現程序崩潰并不可怕&a…

構建安全的Xml Web Service系列之如何察看SoapMessage

上一篇文章地址&#xff1a;構建安全的Xml Web Service系列一之初探使用Soap頭 (5-22 12:53) 要分析Xml Web Service的安全性&#xff0c;首先要解決的問題是我們能了解和清楚Soap消息的格式和內容&#xff0c;如果獲得不了SoapMessage&#xff0c;分析如何能構建安全Xml w…

前端高效開發必備的 js 庫梳理

之前有很多人問學好前端需要學習哪些 js 庫, 主流框架應該學 vue 還是 react ? 針對這些問題, 筆者來說說自己的看法和學習總結.首先我覺得在學習任何知識之前必須要有一個明確的學習目標, 知道自己為什么要學它, 而不是看網上說的一股腦的給你灌輸各種知識, 讓你學習各種庫, …

交叉報表crosstab隱藏列名顯示_SAP軟件 報表查詢之 輸出格式設置

SAP不僅是功能強大、邏輯嚴謹的ERP軟件&#xff0c;還提供了強大的報表查詢功能。SAP的ALV報表展示功能是SAP的一大特點&#xff0c;實現了類似于EXCEL的功能。使用好ALV報表功能可以方便用戶從SAP中取到想要的數據&#xff0c;尤其是財務用戶。大家在使用SAP報表時&#xff0c…

CSS HACK 區別 IE6、IE7、IE8、Firefox兼容性

轉載鏈接&#xff1a;http://developer.51cto.com/art/201009/226787_1.htm 本文向大家描述一下如何使用CSS HACK區別IE6、IE7、IE8、Firefox兼容性問題&#xff0c;針對不同的瀏覽器寫不同的CSS code的過程&#xff0c;就叫CSS hack,也叫寫CSS hack&#xff0c;相信你對本文介…

Flex sdk4 布局與更新

在flex中,主要使用LayoutManager來驅動組件的度量和布局策略, LayoutManager實現一個單例,在Application類構造函數中創建: 1 public functionApplication()2 {3 UIComponentGlobals.layoutManager ILayoutManager(4 Singleton.getInstance("mx.managers::ILayoutManager&…

linux PROC文件系統詳解

/proc文件系統下的多種文件提供的系統信息不是針對某個特定進程的&#xff0c;而是能夠在整個系統范圍的上下文中使用。可以使用的文件隨系統配置的變化而變化。命令procinfo能夠顯示基于其中某些文件的多種系統信息。以下詳細描述/proc下的文件。----------------------------…

seo每日一貼_白楊SEO:我看ZAC的外貿SEO應該怎樣做?(策略篇)

前言&#xff1a;這是白楊SEO公眾號更新第64篇。本該寫寫頭條SEO啥的&#xff0c;最近在師徒培訓講站內SEO時有旁聽同學提到后面講講谷歌SEO怎么樣&#xff0c;因為谷歌全世界搜索市場占有率&#xff0c;所以外貿SEO最主要還是做谷歌SEO。以白楊特意又去了前輩ZAC的SEO每日一貼…

Can't connect to local MySQL server through socket '/tmp/mysql.sock'

轉載鏈接&#xff1a;http://blog.csdn.net/ixidof/article/details/5958904 摘要&#xff1a;解決不能通過mysql .sock連接MySQL問題 這個問題主要提示是&#xff0c;不能通過 /tmp/mysql .sock連到服務器&#xff0c;而php標準配置正是用過/tmp/mysql .sock&#xff0c;但是…

[轉]網頁柵格系統研究(2):蛋糕的切法

[出自]http://lifesinger.org/blog/2008/10/grid-system-2/首先澄清一個應用場景問題。研究&#xff08;1&#xff09;中指出&#xff0c;對于結構復雜的網站&#xff0c;不少設計師們喜歡采用960固定寬度布局。但要注意的是&#xff0c;960并不是萬能鑰匙&#xff0c;大部分網…

Vue3響應式原理

關注若川視野&#xff0c;回復"pdf" 領取資料&#xff0c;回復"加群"&#xff0c;可加群長期交流學習本文結構- 關于Vue3- Vue2響應式原理回顧- Vue3響應式方案- Vue3響應式原理- 手寫mini版Vue3響應式本文共計&#xff1a;2349字2圖預計閱讀時間&#xff…

python二值化 感興趣區域_Python+OpenCV感興趣區域ROI提取方法

方法一&#xff1a;使用輪廓步驟1"""src為原圖"""ROI np.zeros(src.shape, np.uint8) #感興趣區域ROIproimage src.copy() #復制原圖"""提取輪廓"""proimagecv2.cvtColor(proimage,cv2.COLOR_BGR2GRAY) #轉換成…

error while loading shared libraries: libmysqlclient.so.16: cannot open

轉載鏈接&#xff1a;http://blog.sina.com.cn/s/blog_4ab24dd50100wnkv.html 問題解決辦法&#xff1a; locate libmysqlclient.so.16 如我的mysql安裝在/usr/local/mysql下&#xff0c;則結果為 /usr/local/mysql/lib/mysql/libmysqlclient.so.16 vi /etc/ld.so.conf 增…

編譯cvaux錯誤的原因

平臺vc6.0;在debug模式下編譯cvaux時會提示三個錯誤&#xff1a;error C2039: foreground_regions : is not a member of CvFGDStatModelerror C2039: foreground_regions : is not a member of CvFGDStatModelerror C2039: foreground_regions : is not a member of CvGaussBG…

找準切入點,調試看源碼,事半功倍

關注若川視野&#xff0c;回復"pdf" 領取資料&#xff0c;回復"加群"&#xff0c;可加群長期交流學習最近寫了很多源碼分析相關的文章&#xff0c;React、Vue 都有&#xff0c;想把我閱讀源碼的一些心得分享給大家。React&#xff1a;React 架構的演變 - 從…

Android布局大全

Android的界面是有布局和組件協同完成的&#xff0c;布局好比是建筑里的框架&#xff0c;而組件則相當于建筑里的磚瓦。組件按照布局的要求依次排列&#xff0c;就組成了用戶所看見的界面。 所有的布局方式都可以歸類為ViewGroup的5個類別&#xff0c;即ViewGroup的5個直接子類…