Python中可迭代對象、迭代器以及iter函數的兩個用法詳解

2020-12-08 騰訊網

在Python中,有這兩個概念容易讓人混淆。第一個是可迭代對象(Iterable),第二個是迭代器(Iterator),第三個是生成器(Generator),這裡暫且不談生成器。

可迭代對象

列表、元組、字符串、字典等都是可迭代對象,可以使用for循環遍歷出所有元素的都可以稱為可迭代對象(Iterable)。在Python的內置數據結構中定義了Iterable這個類,在collections.abc模塊中,我們可以用這個來檢測是否為可迭代對象

這些數據結構之所以能稱之為Iterable,是因為其內部實現了__iter__()方法,從而可迭代。當我們使用for循環時,解釋器會調用內置的iter()函數,調用前首先會檢查對象是否實現了__iter__()方法,如果有就調用它獲取一個迭代器(接下來會講)。加入沒有__iter__()方法,但是實現了__getitem__()方法,解釋器會創建一個迭代器並且按順序獲取元素。如果這兩個方法都沒有找到,就會拋出TypeError異常。下面我們自定義對象,分別實現這兩個方法(getitem(), iter())

如上所示,這裡沒有實現__iter__方法,只實現了__getitem__方法,也使得Myobj稱為可迭代對象。

下面我們實現__iter__方法,這裡使用了yield語法用來產出值(這裡需要生成器的知識)

這裡同樣讓對象稱為可迭代對象。

迭代器

迭代器是一個可以記住遍歷的位置的對象。 迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。

如上圖所示,迭代器(Iterator)繼承可迭代(Iterable),迭代器必須實現__iter__方法和__next__方法。其中__next__方法用於產出下一個元素。

由繼承圖可見,迭代器一定是可迭代對象,可迭代對象不一定是迭代器

迭代器有兩個基本的方法:iter() 和 next()。

我們使用iter(iterable)即可把可迭代對象轉換成迭代器 使用next(iterator)來獲取迭代器的下一個值

如上所示,因為對象實現了__next__方法,我們可以通過next(iterator)來獲取迭代器的下一個值,直到沒有值了,拋出StopIteration異常結束。

迭代器的背後

迭代器Iterator是一個抽象基類,它定義在_collections_abc.py中

Iterator源碼如下

可以看到,它實現了__subclasshook__方法,即不用顯式繼承Iterator,只需要實現__iter__和__next__方法即可稱為Iterator的虛擬子類。這裡凸現了Python的鴨子類型,實現特定的「協議」即可擁有某種行為。

另外,它自己也定義了__iter__方法,當我們使用iter(Iterator)時直接返回自己,不做任何處理。

iter()函數的兩個用法

官方文檔中給出了說明:

第一個用法:iter(iterable) -> iterator (把可迭代對象轉換為迭代器)

第二個用法:iter(callable, sentinel) -> iterator (第一個參數:任何可調用對象,可以是函數,第二個是標記值,當可調用對象返回這個值時,迭代器拋出StopIteration異常,而不產出標記值)

上面代碼的流程:test_iter函數從values列表中隨機挑選一個值並返回,調用iter(callable, sentinel)函數,把sentinel標記值設置為2,返回一個callable_iterator實例,遍歷這個特殊的迭代器,如果函數返回標記值2,直接拋出異常退出程序。這就是iter函數的鮮為人知的另一個用法。

相關焦點

  • 一文解開可迭代對象和迭代器的神秘面紗
    (Iterable)可迭代對象指的就是可以迭代的對象,或者說可以作用於for循環的都是可迭代對象。那接下來我們判斷一下到底list,set,dict,tuple是不是可迭代類型。判斷是不是可迭代類型可以使用isinstance和Iterable對象。
  • python中常見的對象辨析(可迭代對象、迭代器對象、生成器對象)
    一 可迭代對象IterableA.定義可作用於for循環的對象叫可迭代對象B.包括1.集合數據類型 序列,字典,集合2.迭代器對象C.訪問可迭代對象1.集合數據類型使用各自的訪問方法2.迭代器對象使用迭代器對象訪問的方法D.注意1.具有
  • Python進階:迭代器與迭代器切片
    在前兩篇關於 Python 切片的文章中,我們學習了切片的基礎用法、高級用法、使用誤區,以及自定義對象如何實現切片用法(相關連結見文末)。本文是切片系列的第三篇,主要內容是迭代器切片。迭代器是 Python 中獨特的一種高級特性,而切片也是一種高級特性,兩者相結合,會產生什麼樣的結果呢?
  • Python 迭代器和 C++ 迭代器,最大的不同竟然是……
    迭代器協議規定:如果一個類想要成為可迭代對象(Iterable Object),則其必須實現__iter__方法,且其返回值需要是一個實現了__next__方法的對象。即:實現了__iter__方法的類將成為可迭代對象,而實現了__next__方法的類將成為迭代器。
  • 雲計算開發學習筆記:Python3迭代器與生成器
    迭代器迭代是Python最強大的功能之一,是訪問集合元素的一種方式。迭代器是一個可以記住遍歷的位置的對象。迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。
  • Python中的迭代器和生成器,模塊和第三方模塊都是些什麼?
    苦短人生,我用Python1.迭代器迭代器對象要求支持迭代器協議的對象,在Python中,支持迭代器協議就是實現對象的__iter__()和__next__()方法。其中__iter__()方法返回迭代器對象本身;__next__()方法返回容器的下一個元素,在結尾時引發StopIteration異常。
  • 深入理解循環和迭代
    在Python中,我們不能通過使用索引手動遍歷每個可迭代對象。這對於不是序列的可迭代對象根本不起作用。迭代器在Python中,迭代器可以用於for循環。什麼是迭代器?它是驅動可迭代對象的一類對象。函數用上面的可迭代對象生成迭代器。
  • Python迭代器和生成器,三個練習你絕對能搞定
    1、 迭代器1.1 容器首先,在了解迭代器之前,需要知道什麼是容器一切都是對象,對象的抽象就是類,而對象的集合就是容器。容器,就是有多個對象組成的東西。比如:列表[0,1,2],元組(1,2,3),字典{』0:'0','1':"1'} 集合{1,2,3}都是容器所有的容器都是可迭代對象,也就是可以遍曆元素。
  • Python——迭代器的幾個高級用法
    dropwhile是itemtools當中的一個函數,它可以 接收一個我們自定義的過濾函數和迭代器重新生成一個新的迭代器 ,這個新的迭代器當中會過濾掉之前迭代器頭部不符合我們要求的數據:在剛才的例子當中我們想要過濾掉頭部加了#注釋的部分,我們可以這麼操作:from itertools
  • 理解 Python 的 for 循環
    如果你對 Python 的迭代並不是很熟悉的話,Python中的迭代:for、while、break、以及continue語句是一個不錯的切入點。Python 中,for 循環用於遍歷一個迭代對象的所有元素。循環內的語句段會針對迭代對象的每一個元素項目都執行一次。暫且可以將迭代對象想像成一個對象集合,我們可以一個個遍歷裡面的元素。我們將在下一節對迭代器和迭代對象作詳細說明。
  • Python進階:全面解讀高級特性之切片!
    要使一個對象可迭代,就要實現可迭代協議,即需要實現__iter__() 魔術方法,換言之,只要實現了這個魔術方法的對象都是可迭代對象。那怎麼判斷一個對象是否實現了這個方法呢?這幾種方法中最值得一提的是 iter() 方法,它是 Python 的內置方法,其作用是將可迭代對象變成迭代器 。這句話可以解析出兩層意思:(1)可迭代對象跟迭代器是兩種東西;(2)可迭代對象能變成迭代器。實際上,迭代器必然是可迭代對象,但可迭代對象不一定是迭代器。兩者有多大的區別呢?
  • Python range 對象
    range 對象通常用於在 for 循環中循環指定的次數。range 對象是不可變數字序列,是可迭代對象,不是迭代器。
  • Python中的for循環
    # 循環允許我們重複執行一個代碼或代碼塊 # python中的循環 # for循環 # while循環 # for循環是一種迭代循環機制,而while循環是條件循環,迭代即重複相同的邏輯操作
  • python:控制流程 - for迭代循環
    for迭代的要點for 後面需要接上可迭代對象for會依次取出可迭代對象中的元素5.continue的用法:continue和break類似,但是continue不會終止循環,而是結束本次循環135解析: 如果是可變對象,一定不要再循環的往裡面插入東西。判斷一個對象是不是可迭代對象:1.直接放到for裡面。
  • python教程:3個非常有用的內置函數
    (function,iterable) 解釋:把迭代器通過function函數進行過濾出想要的數據 用法:可以設置一個迭代器,然後把相同屬性的元素過濾出來,如下所示
  • 一日一技:舉例說明python中的map()方法
    map()函數Python 的map()方法,作為輸入提供的迭代器的所有元素應用函數。 例如,迭代器可以是列表,元組,集合,字典,字符串,並且它返回可迭代的映射對象。 另外,map()是python的內置函數。
  • Python要點總結,我使用了100個小例子!
    ,也會返回TrueIn [26]: issubclass(int,(int,float))Out[26]: True38 iter(object, sentinel)返回一個可迭代對象, sentinel可省略In [72]: lst = [1,3,5]In [73]: for i in iter(lst
  • Qt系列文章之十(Qt 數據類型介紹以及迭代器使用下)
    Java類型迭代器Java類型迭代器集合總覽  java風格的迭代器是Qt 4中的新元素,是Qt應用程式中使用的標準迭代器。它們使用起來比STL風格的迭代器更方便,但效率稍低一些。它們的API模仿Java的迭代器類。
  • 一篇文章掌握 Python 內置 zip() 的全部內容
    zip() 是 Python 中最好用的內置類型之一,它可以接收多個可迭代對象參數,再返回一個迭代器,可以把不同可迭代對象的元素組合起來。我之前寫迭代器系列的時候,在《Python進階:設計模式之迭代器模式》中簡單地介紹過它,前幾天翻譯了 Python 3.10 採納的 PEP-618 ,介紹了它將會迎來的變更。
  • Python生成器那些事兒
    最後會通過碼農工作中一個實際的例子,來了解不同實現的好壞。什麼是生成器?生成器(Generator)是一個非常強大的迭代器。其按照一定的算法生成一個序列。包含yield的函數會返回一個生成器。說明函數gen返回了一個迭代器。可以用next來進行迭代,迭代到最後會返回一個StopIteration的異常。與普通迭代器不同的是,生成器只能迭代一次。如果我們接著上面的代碼重新迭代,會發現沒有任何輸出。