[轉載] Python 迭代器 深入理解 與應用示例

參考鏈接: Python | 可迭代和迭代器之間的區別

本篇文章簡單談談可迭代對象,迭代器和生成器之間的關系。

?

?

三者簡要關系圖

?

?

?

?

?

可迭代對象與迭代器

?

剛開始我認為這兩者是等同的,但后來發現并不是這樣;下面直接拋出結論:

1)可迭代對象包含迭代器。2)如果一個對象擁有__iter__方法,其是可迭代對象;如果一個對象擁有next方法,其是迭代器。3)定義可迭代對象,必須實現__iter__方法;定義迭代器,必須實現__iter__和next方法。

?

?

你也許會問,結論3與結論2是不是有一點矛盾?既然一個對象擁有了next方法就是迭代器,那為什么迭代器必須同時實現兩方法呢?

因為結論1,迭代器也是可迭代對象,因此迭代器必須也實現__iter__方法。

?

?

介紹一下上面涉及到的兩個方法:

1)__iter__()

該方法返回的是當前對象的迭代器類的實例。因為可迭代對象與迭代器都要實現這個方法,因此有以下兩種寫法。

寫法一:用于可迭代對象類的寫法,返回該可迭代對象的迭代器類的實例。

寫法二:用于迭代器類的寫法,直接返回self(即自己本身),表示自身即是自己的迭代器。

也許有點暈,沒關系,下面會給出兩寫法的例子,我們結合具體例子看。

?

2)next()

?

返回迭代的每一步,實現該方法時注意要最后超出邊界要拋出StopIteration異常。

?

下面舉個可迭代對象與迭代器的例子:

?

?

?

??

? ?[python]?

? ?view plain

? ? copy

? ?

? ?

? ?

??

?

?#!/usr/bin/env python? # coding=utf-8? ? ? class MyList(object):? ? ? ? ? ? # 定義可迭代對象類? ? ? ? def __init__(self, num):? ? ? ? ? self.data = num? ? ? ? ? # 上邊界? ? ? ? def __iter__(self):? ? ? ? ? return MyListIterator(self.data)? # 返回該可迭代對象的迭代器類的實例? ? ? class MyListIterator(object):? ? # 定義迭代器類,其是MyList可迭代對象的迭代器類? ? ? ? def __init__(self, data):? ? ? ? ? self.data = data? ? ? ? ?# 上邊界? ? ? ? ? self.now = 0? ? ? ? ? ? ?# 當前迭代值,初始為0? ? ? ? def __iter__(self):? ? ? ? ? return self? ? ? ? ? ? ? # 返回該對象的迭代器類的實例;因為自己就是迭代器,所以返回self? ? ? ? def next(self):? ? ? ? ? ? ? # 迭代器類必須實現的方法? ? ? ? ? while self.now < self.data:? ? ? ? ? ? ? self.now += 1? ? ? ? ? ? ? return self.now - 1? # 返回當前迭代值? ? ? ? ? raise StopIteration? ? ? # 超出上邊界,拋出異常? ? ? my_list = MyList(5)? ? ? ? ? ? ? # 得到一個可迭代對象? print type(my_list)? ? ? ? ? ? ? # 返回該對象的類型? ? my_list_iter = iter(my_list)? ? ?# 得到該對象的迭代器實例,iter函數在下面會詳細解釋? print type(my_list_iter)? ? ? for i in my_list:? ? ? ? ? ? ? ? # 迭代? ? ? print i??

?

運行結果:

?

?

問題:上面的例子中出現了iter函數,這是什么東西?和__iter__方法有關系嗎?

?

其實該函數與迭代是息息相關的,通過在Python命令行中打印“help(iter)”得知其有以下兩種用法。

?

?

用法一:iter(callable, sentinel)

?

不停的調用callable,直至其的返回值等于sentinel。其中的callable可以是函數,方法或實現了__call__方法的實例。

?

?

用法二:iter(collection)

?

1)用于返回collection對象的迭代器實例,這里的collection我認為表示的是可迭代對象,即該對象必須實現__iter__方法;

事實上iter函數與__iter__方法聯系非常緊密,iter()是直接調用該對象的__iter__(),并把__iter__()的返回結果作為自己的返回值,故該用法常被稱為“創建迭代器”。

?

2)iter函數可以顯示調用,或當執行“for i in obj:”,Python解釋器會在第一次迭代時自動調用iter(obj),之后的迭代會調用迭代器的next方法,for語句會自動處理最后拋出的StopIteration異常。

?

通過上面的例子,相信對可迭代對象與迭代器有了更具體的認識,那么生成器與它們有什么關系呢?下面簡單談一談

?

?

生成器

?

生成器是一種特殊的迭代器,生成器自動實現了“迭代器協議”(即__iter__和next方法),不需要再手動實現兩方法。

生成器在迭代的過程中可以改變當前迭代值,而修改普通迭代器的當前迭代值往往會發生異常,影響程序的執行。

?

看一個生成器的例子:

?

?

??

? ?[python]?

? ?view plain

? ? copy

? ?

? ?

? ?

??

?

?#!/usr/bin/env python? # coding=utf-8? ? ? def myList(num):? ? ? # 定義生成器? ? ? now = 0? ? ? ? ? ?# 當前迭代值,初始為0? ? ? while now < num:? ? ? ? ? val = (yield now)? ? ? ? ? ? ? ? ? ? ? # 返回當前迭代值,并接受可能的send發送值;yield在下面會解釋? ? ? ? ? now = now + 1 if val is None else val? # val為None,迭代值自增1,否則重新設定當前迭代值為val? ? my_list = myList(5)? ?# 得到一個生成器對象? ? print my_list.next()? # 返回當前迭代值? print my_list.next()? ? my_list.send(3)? ? ? ?# 重新設定當前的迭代值? print my_list.next()? ? print dir(my_list)? ? # 返回該對象所擁有的方法名,可以看到__iter__與next在其中??

?

運行結果:

?

?

具有yield關鍵字的函數都是生成器

,yield可以理解為return,返回后面的值給調用者。不同的是return返回后,函數會釋放,而生成器則不會。在直接調用next方法或用for語句進行下一次迭代時,生成器會從yield下一句開始執行,直至遇到下一個yield。

?

#生成器函數,函數里只要有yield關鍵字def gen_func():

? ? yield 1

? ? yield 2

? ? yield 3

?

?

def fib(index):

? ? if index <= 2:

? ? ? ? return 1

? ? else:

? ? ? ? return fib(index-1) + fib(index-2)

?

?

def fib2(index):

? ? re_list = []

? ? n,a,b = 0,0,1

? ? while n<index:

? ? ? ? re_list.append(b)

? ? ? ? a,b = b, a+b

? ? ? ? n += 1

? ? return re_list

?

?

def gen_fib(index):

? ? n,a,b = 0,0,1

? ? while n<index:

? ? ? ? yield b

? ? ? ? a,b = b, a+b

? ? ? ? n += 1

?

?

for data in gen_fib(10):

? ? print (data)

# print (gen_fib(10))

# 斐波拉契 0 1 1 2 3 5 8

#惰性求值, 延遲求值提供了可能

?

?

def func():

? ? return 1

?

?

if __name__ == "__main__":

? ? #生成器對象, python編譯字節碼的時候就產生了,

? ? gen = gen_func()

? ? for value in gen:

? ? ? ? print (value)

? ? # re = func()

? ? # pass

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

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

相關文章

Python程序查找表示O(1)復雜度的數字所需的位數

Problem statement 問題陳述 Find total Number of bits required to represent a number in binary 查找以二進制表示數字所需的總位數 Example 1: 范例1&#xff1a; input : 10output: 4Example 2: 范例2&#xff1a; input : 32output : 6Formula used: 使用的公式&am…

正則split

string content "第1行導入失敗&#xff0c;失敗原因為&#xff1a; 《加班原因》字段必填";string[] resultString Regex.Split(content, "失敗原因為&#xff1a;", RegexOptions.IgnoreCase);foreach (string i in resultString){Console.WriteLine(i…

將八進制數制轉換為二進制,十進制和十六進制數制

1)將八進制數制轉換為二進制數制 (1) Conversion of Octal Number System to Binary Number System) To convert octal numbers into binary numbers, we can use the relationship between octal and binary numbers. 要將八進制數轉換為二進制數&#xff0c;我們可以使用八進…

[轉載] Python的生成器

參考鏈接&#xff1a; Python中的生成器Generator Python的生成器 什么是生成器 創建python迭代器的過程雖然強大&#xff0c;但是很多時候使用不方便。生成器是一個簡單的方式來完成迭代。簡單來說&#xff0c;Python的生成器是一個返回可以迭代對象的函數。 怎樣創建生…

想提高用戶訪問的響應速度和成功率還不趕快學習CDN

2019獨角獸企業重金招聘Python工程師標準>>> 課程介紹 CDN可以將源站內容分發至最接近用戶的節點&#xff0c;使用戶可就近取得所需內容&#xff0c;提高用戶訪問的響應速度和成功率。解決因分布、帶寬、服務器性能帶來的訪問延遲問題&#xff0c;適用于站點加速、點…

[轉載] python迭代器、生成器和裝飾器

參考鏈接&#xff1a; 有效地在Python中使用迭代 文章目錄 生成器生成器表達式(generator expression)通過使用yield關鍵字定義生成器并行前戲高潮 迭代器迭代器概述iter()函數 創建迭代器創建一個迭代器(類)內置迭代器工具count無限迭代器cycle 無限迭代器&#xff0c;從一個…

java中的starts_Java Math類靜態double nextAfter(double starts,double direction)示例

java中的starts數學類靜態double nextAfter(雙向啟動&#xff0c;雙向) (Math Class static double nextAfter(double starts , double directions) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the double …

Python 核心編程(第二版)——條件和循環

Python 中的 if 子句由三部分組成: 關鍵字本身&#xff0c;用于判斷結果真假的條件表達式&#xff0c; 以及當表達式為真或者非零時執行的代碼塊。if 語句的語法如下: if expression: expr_true_suite 單個 if 語句可以通過使用布爾操作符 and , or 和 not實現多重判斷條件或…

[轉載] 【python魔術方法】迭代器(__iter__和__next__)

參考鏈接&#xff1a; Python __iter __()和__next __()| 將對象轉換為迭代器 文章目錄 __iter__ 和 __next__真正的迭代器總結 python里面有很多的以__開始和結尾的函數&#xff0c;利用它們可以完成很多復雜的邏輯代碼&#xff0c;而且提高了代碼的簡潔性&#xff0c;本文主…

Silverlight 異步單元測試

Silverlight 中的很多操作都是異步的&#xff0c;很多情況下要求單元測試也是異步的&#xff0c;但是介紹異步單元測試的文檔很少。通過對 Silverlight Toolkit 中的 Microsoft.Silverlight.Testing 和 Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight 這兩個文件…

網絡拓撲 令牌環網 以太網_以太網連接中網絡拓撲的類型及其框架 以太網技術...

網絡拓撲 令牌環網 以太網A topology explains how physically the network is designed or what is the structure of the network. These designs are both physical and logical. There are many network topologies 4 like Bus, Star, Ring, and Mesh. But only two types …

Wafer晶圓封裝工藝介紹

芯片封裝的目的&#xff08;The purpose of chip packaging&#xff09;: 芯片上的IC管芯被切割以進行管芯間連接&#xff0c;通過引線鍵合連接外部引腳&#xff0c;然后進行成型&#xff0c;以保護電子封裝器件免受環境污染&#xff08;水分、溫度、污染物等&#xff09;&…

[轉載] Python中的解析式和生成器表達式

參考鏈接&#xff1a; Python | 生成器表達式 解析式和生成器表達式 列表解析List Comprehension 語法 [返回值 for 元素 in 可迭代對象 if 條件]使用中括號[],內部是for循環&#xff0c;if條件語句可選&#xff0c;會返回一個新的列表 列表解析試優點 編譯器會優化&…

java 數字字母進位_使用帶有進位的8085微處理器將兩個8位數字相乘

java 數字字母進位Problem statement: 問題陳述&#xff1a; Multiplication of two 8 bits numbers using 8085 microprocessor with carry. 使用帶有進位的8085微處理器將兩個8位數字相乘。 Algorithm: 算法&#xff1a; Load HL pair with initial data using LHLD comma…

[轉載] Python3.0中普通方法、類方法和靜態方法的比較

參考鏈接&#xff1a; Python中的類方法與靜態方法 一、語法區別 剛接觸Python中的面向對象&#xff0c;對于類方法和靜態方法難以區分&#xff0c;通過查找知乎、CSDN論壇&#xff0c;廢了好大的勁思路才逐漸明朗&#xff0c;所以就總結順便分享一下。 首先開始編輯代碼 # 普…

iOS:個人淺談工廠模式

一、什么是工廠方法&#xff1f; 正式的解釋是&#xff1a;在基類中定義創建對象的一個接口&#xff0c;讓子類決定實例化哪個類。工廠方法讓一個類的實例化延遲到子類中進行。工廠方法要解決的問題是對象的創建時機&#xff0c;它提供了一種擴展的策略&#xff0c;很好地符合了…

scanf 輸入十六進制_使用C語言中的scanf()在字符變量中輸入十進制,八進制和十六進制值...

scanf 輸入十六進制Here, we will declare an unsigned char variable and input different formats value like decimal format, octal format and hexadecimal format. 在這里&#xff0c;我們將聲明一個無符號的char變量&#xff0c;并輸入不同格式的值&#xff0c;例如十進…

[轉載] Python中pass的作用

參考鏈接&#xff1a; 如何在Python中編寫空函數&#xff1f;請使用 pass語句 空語句 do nothing保證格式完整保證語義完整 以if語句為例&#xff0c;在c或c/java中&#xff1a; if(true) ; //do nothing else { //do something } 對應于python就要這樣寫&#xff…

wrf 嵌套網格作用_在網格系統中使用響應列,嵌套列和偏移列 引導程序

wrf 嵌套網格作用介紹 (Introduction) In the previous article, we have learnt what is grid and grid system and how it works? Now, we will learn about how Responsive column, Nesting Columns and Offset Columns works and how to use them? If you have any doubt…

[看書筆記]《深入java虛擬機》——java體系結構(二)

java虛擬機的三種含義&#xff1a; - 抽象的規范 - 一個具體的實現 - 一個運行中的虛擬機實例 ---------------------java虛擬機的生命周期&#xff1a; java虛擬機實例的天職就是負責運行一個java程序。 啟動一個java程序&#xff0c;一個虛擬機實例誕生了&#xff1b;程序關閉…