日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python的迭代器无法输出值_python迭代器和生成器

發布時間:2025/4/16 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python的迭代器无法输出值_python迭代器和生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

人生還早,誰能笑到最后呢,堅持吧!

1.迭代器協議

由于生成器自動實現了迭代器協議,我們有必要了解迭代器協議是什么,才能更好的理解生成器。

1)迭代器協議:對象要提供__next()__方法,它要么返回迭代中的下一個對象,要么引起一個StopIteration錯誤,終止迭代

2)可迭代對象:實現了迭代器協議的對象

3)協議是一種約定,可迭代對象實現了迭代器協議,python的內部工具(如for循環,sum,min,max函數等)使用迭代器協議訪問對象。

for循環的本質:循環所有對象,全都是使用迭代器協議

(字符串,列表,元組,字典,集合,文件對象)這些都不是可迭代對象,只不過在for循環式,調用了他們內部的__iter__方法,把他們變成了可迭代對象

list = ['a','b',1,2]

# for i in list:

# print(i)

list_iter = list.__iter__()#調用__iter__方法將list對象變成可迭代對象

print(list_iter.__next__())依次調用,知道引起StopIteration錯誤

print(list_iter.__next__())

print(list_iter.__next__())

print(list_iter.__next__())

用while循環模擬for循環做的事情

list_iter = list.__iter__()

while True:

try:

print(list_iter.__next__())

except StopIteration:

print('迭代完畢,可以終止')

break

迭代器對象的本質是一種數據流,它只是一個有序的序列,我們不能提前知道它的長度,只有不斷通過__next__()取出下一個值。

Interator甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的。

優點

1):迭代器提供了一種不依賴于索引的取值方式,這樣就可以遍歷那些沒有索引的可迭代對象了(字典,集合,文件)

2):迭代器與列表比較,迭代器是惰性計算的,,只有在需要返回下一個數據時才計算,更節省內存

缺點:

1):無法獲取迭代器的長度,使用不如列表索引取值靈活

2):一次性的,只能往后取值,不能倒著取值

如何查看一個對象是不是可迭代對象和迭代器對象

from collections import Iterable,Iterator#導入模塊

list = ['a','b',1,2]

list_iter = list.__iter__()

#isinstance

print(isinstance(list,Iterable))#是否是可迭代對象

print(isinstance(list,Iterator))#是否是迭代器對象

print(isinstance(list_iter,Iterable))

print(isinstance(list_iter,Iterator))

小結:

凡是可作用于for循環的對象都是Iterable類型;

凡是可作用于next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列,也就是說你需要取值時才給你取;

集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。

協程函數

如果在一個函數內部yield的使用方式是表達式形式的話,如x=yield,那么該函數稱為協程函數,比線程更小

def eater(name):

food_list=[]

while True:

food=yield food_list

food_list.append(food)#因為有yied

e=eater('鐵根') #一個生成器的內存地址

print(next(e)) #初始化迭代器

print(e.send('包子'))

print(e.send('韭菜餡包子'))

print(e.send('大蒜包子'))

2.生成器

通過列表生成式,我們可以創建一個列表。但是我們知道受內存的限制,我們的列表容量是有限的,而且創建包含100萬個元素的列表,我們只用到前幾個,剩下的都是浪費內存空間。

所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出后續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。

要創建一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就創建了一個generator:

l=[x*x for x in range(10)]

print(l)

g=(x*x for x in range(10))

print(g)

打印結果

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

at 0x0000000001E70F10>

取generator值用__next__()一個一個打印出來

print(g.__next__())

print(g.__next__())

print(g.__next__())

print(g.__next__())

print(g.__next__())

print(g.__next__())

0

1

4

9

16

25

generator也是可迭代對象,所以也可以使用for循環

for i in g:

print(i)

0

1

4

9

16

25

36

49

64

81

所以,我們創建了一個generator后,基本上永遠不會調用next(),而是通過for循環來迭代它,并且不需要關心StopIteration的錯誤。

generator非常強大。如果推算的算法比較復雜,用類似列表生成式的for循環無法實現的時候,還可以用函數來實現。

比如,著名的斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得到:

1, 1, 2, 3, 5, 8, 13, 21, 34, ...

斐波拉契數列用列表生成式寫不出來,但是,用函數把它打印出來卻很容易:

def fib(max):

n, a, b = 0, 0, 1

while n < max:

print(b)

a, b = b, a + b

n = n + 1

return 'done'

fib(20)

1

1

2

3

5

8

13

21

34

55

89

144

233

377

610

987

1597

2584

4181

6765

仔細觀察,可以看出,fib函數實際上是定義了斐波拉契數列的推算規則,可以從第一個元素開始,推算出后續任意的元素,這種邏輯其實非常類似generator。

也就是說,上面的函數和generator僅一步之遙。要把fib函數變成generator,只需要把print(b)改為yield b就可以了:

def fib(max):

n, a, b = 0, 0, 1

while n < max:

yield b

a, b = b, a + b

n = n + 1

return 'done'

f = fib(6)

print(f)

這里,最難理解的就是generator和函數的執行流程不一樣。函數是順序執行,遇到return語句或者最后一行函數語句就返回。而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。

定義generator的另一種方法。如果一個函數定義中包含yield關鍵字,那么這個函數就不再是一個普通函數,而是一個generator

我們把函數變成generator后,基本上也不再使用__next__()方法,都是用for循環來迭代,但是用for循環調用generator時,發現拿不到generator的return語句的返回值。

def fib(max):

n, a, b = 0, 0, 1

while n < max:

# print(b)

yield b

a, b = b, a + b

n = n + 1

return 'done'

for i in fib(5):

print(i)

1

1

2

3

5

如果想要拿到返回值,必須捕獲StopIteration錯誤,返回值包含在StopIteration的value中:

while True:

try:

x=next(g)

print(x)

except StopIteration as e:

print('Generator return value:',e.value)

break

2

3

5

Generator return value: done

看到一張圖方便理解列表等容器,生成器,可迭代對象,迭代器之間的關系

小結:

generator可以是表達式也可以是函數,它保存的是算法,同時它是iterable對象,它也是一個generator。

總結

以上是生活随笔為你收集整理的python的迭代器无法输出值_python迭代器和生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。