程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

一起看看Python中的迭代器&生成器

編輯:Python

目錄:

  • 每篇前言:
  • 1.迭代器(iterator)
    • (1)列表推導式:能夠簡潔的構造一個新列表
    • (2)升級篇 輸出1-9之間的偶數 :
    • (2)又升一級 如何打印出多個值呢?
    • 集合推導式&字典推導式也就呼之欲出了:
    • 小拓展:
    • 知識點補給站:
    • 小拓展:
    • 2.生成器(generator)
    • (1)元組推導式
    • (2)yield
  • 迭代器生成器總結:

每篇前言:

  • 作者介紹:【孤寒者】—CSDN全棧領域優質創作者、HDZ核心組成員、華為雲享專家Python全棧領域博主、CSDN原力計劃作者

  • 本文已收錄於Python全棧系列專欄:《Python全棧基礎教程》
  • 熱門專欄推薦:《Django框架從入門到實戰》、《爬蟲從入門到精通系列教程》、《爬蟲高級》、《前端系列教程》、《tornado一條龍+一個完整版項目》。
  • ​本專欄面向廣大程序猿,為的是大家都做到Python從入門到精通,同時穿插有很多很多習題,鞏固學習。
  • 訂閱專欄後可私聊進一千多人Python全棧交流群(手把手教學,問題解答);進群可領取Python全棧教程視頻 + 多得數不過來的計算機書籍:基礎、Web、爬蟲、數據分析、可視化、機器學習、深度學習、人工智能、算法、面試題等。
  • 加入我一起學習進步,一個人可以走的很快,一群人才能走的更遠!

可能很多看了我之前文章的小伙伴會說,我在前面的文章中不是都已經講的很細了嗎?為啥又出一篇文章來講!
俗話說得好,重要的事情說三遍,而我想說的是,重要的Python知識點要多講!
同時,本文又來了個新的很重要的知識點——生成器!

1.迭代器(iterator)

迭代是Python最強大的功能之一,是訪問集合元素的一種方式。
迭代器是可以記住遍歷的位置的對象。
迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問結束為止,迭代器只能往前不會後退。

迭代是一個怎樣的過程 ?

  • 就是一個依次從數據結構中拿出東西的過程~

(1)列表推導式:能夠簡潔的構造一個新列表

一般情況下這樣構造一個新列表:

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
li = []
for i in range(1,10):
li.append(i)
print(li) # 輸出為:[1, 2, 3, 4, 5, 6, 7, 8, 9]

列表推導式:

li1 = [i for i in range(1,10)]
print(li1) # 輸出為:[1, 2, 3, 4, 5, 6, 7, 8, 9]

(2)升級篇 輸出1-9之間的偶數 :

(當然也可以使用range(1,10,2)

li3 = [i for i in range(1,10) if i % 2 !=0]
print(li3) # 輸出為:[1, 3, 5, 7, 9]

(2)又升一級 如何打印出多個值呢?

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
li4 = [(i,j) for i in range(1,5) for j in range(1,5)]
print(li4) # 輸出為: [(1, 1), (1, 2), (1, 3), (1, 4),
# (2, 1), (2, 2), (2, 3), (2, 4),
# (3, 1), (3, 2), (3, 3), (3, 4),
# (4, 1), (4, 2), (4, 3), (4, 4)]

集合推導式&字典推導式也就呼之欲出了:

集合推導式:

li5 = {
i for i in range(1,10)}
print(li5) # 輸出為:{1, 2, 3, 4, 5, 6, 7, 8, 9}

字典推導式:

li6 = {
i:j for i in range(1,10) for j in range(1,10)}
print(li6) # 輸出為:{1: 9, 2: 9, 3: 9, 4: 9, 5: 9, 6: 9, 7: 9, 8: 9, 9: 9}

小拓展:

li7 = {
i:j for i,j in enumerate(['吳某','張某'])}
print(li7) # 輸出為:{0: '吳某', 1: '張某'}

注意:是沒有元組推導式的!!!

知識點補給站:

  • 迭代:
    for 迭代變量 in 可迭代對象
    每一次循環都會自動讓“迭代變量”指向“下一個元素”。
  • 可迭代對象指:
    可迭代對象(實現了__iter__這個方法的都是):序列類型和散列類型。
  • 迭代器指:
    迭代器(實現了__iter__和__next__方法的就是,迭代器是一個對象) 只能前進不能後退。
  • 從可迭代對象生成一個迭代器:
    迭代器 = iter(可迭代對象)
    下個值 = next(迭代器)
    來個例子:

列表是一個可迭代對象,dir查看列表方法的時候裡面有__iter__方法,
但列表不是一個迭代器,如何把列表轉換為一個迭代器:

li = [1,2,3,4]
it = iter(li)

獲取迭代器的值?

 for i in it:
print(i) #這樣會取到所有的值

既然是迭代器了,就通過next方法去獲取迭代器的值。這樣做一次只取一個值,可以省內存空間。
next兩種使用方式:

print(it.__next__()) # 輸出為:1
print(next(it)) # 輸出為:2

小拓展:

  • for循環實現原理。
# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
li = [1,2,3,4]
it = iter(li)
try:
while True:
print(next(it))
except Exception as e:
print(e)

輸出為:

1
2
3
4

2.生成器(generator)

問題一: 我們如何自己實現一個可迭代對象 ?

在自定義的類中,要實現 __iter__ 魔術方法
該魔術方法,必須要返回一個 迭代器
(也需要自己實現)

問題二: 是否有更加優雅的方式 ?

生成器!

  • 生成器:返回迭代器的函數。

(1)元組推導式

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
tu = (i for i in range(1,10))
print(type(tu)) # 輸出為:<class 'generator'> 意思是這是個生成器
print(dir(tu)) # 可知tu裡面有方法__iter__和__next__,所以這是個迭代器
print(tu.__next__()) # 既然是一個迭代器,就可以使用next方法取值

(2)yield

  • 凡是有yield的函數都是生成器!

返回這個對象
yield 一個對象->暫停這個函數
等待下次next重新激活

來個例子:

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
def fun(): # 定義生成器,由next函數觸發執行
print('好好學習')
yield 1 #返回一個1 並暫停函數
print('天天向上')
yield 2 #返回一個2 並暫停函數
print('再來一次')
#沒有代碼了,引發StopIteration異常
a = fun()
aa = next(a) # 輸出為: 好好學習
print(aa) # 輸出為: 1
bb = next(a) # 輸出為: 天天向上
print(bb) # 輸出為: 2
# cc = next(a) # 輸出為: 再來一次 並拋出StopIteration異常(大家可以自行run一下看看哦~)
#如果print(type(fun())),會輸出<class 'generator'>,可見這個函數已經是一個生成器了。

再來個例子看看:

# -*- coding: utf-8 -*-
""" __author__ = 孤寒者 """
def fun(ele, n):
count = 0
while True:
if count < n:
count += 1
yield ele
else:
break
a = fun('wumou', 5)
for i in a:
print(i)

迭代器生成器總結:

生成器 與 迭代器 的區別:

  • 生成器,是Python提供的一種非常簡便的語法能讓我們來自己寫出迭代器。
    注意——> 生成器,是一種特殊的迭代器。
  • 生成器指的是一個函數,返回的結果是一個迭代器。
    而迭代器是一個對象。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved