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

歡迎訪問 生活随笔!

生活随笔

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

python

python3 生成器

發布時間:2025/3/15 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3 生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

要說生成器,就必須首先要知道列表的概念;

我們創建一個如下的列表:

ls = [1,2,3,4,5,6,7,8,9]

那么就開辟了一個門牌號為ls的內存區,然后真的把1,2,3,4,5,6,7,8,9這幾個數字放到了內存中;

如果我們在for循環中要根據i的值來獲取一個值的話,我們可以把數據放在上面的ls中,然后通過ls[i]來獲取;這樣的

方式存在巨大的缺點,就是要事先準備好ls中的所有數值;如果很多的話會造成響應慢,內存溢出等問題;

所以就有有了生成器的概念,生成器會指定一個公式,然后每次循環都根據公式計算出當前的值,不用事先生成

所有的值。


一、最簡單的生成器

# -*- coding:utf-8 -*- # Author: Evan Mi# 這是一個最基本的生成器,對應的公式是i*2,i從0到9 # 這樣我們就可以通過迭代的方式來訪問生成的每一個值了 # 它的缺點就是,只能逐一迭代,不能隨意指定i,也不能往前迭代 my_gen_01 = (i*2 for i in range(10)) """ 可以看到my_gen是一個generator對象 """ print(my_gen_01) # <generator object <genexpr> at 0x00000000024FCBA0> # generator對象是一個迭代器對象,所以直接通過next()方法來迭代 while True:try:print(next(my_gen_01)) # 迭代(根據公式計算)except StopIteration as e: # 迭代到沒有元素后會拋出StopIterationprint(e.value)break """ 運行結果: 0 2 4 6 8 10 12 14 16 18 None """ # 用for循環迭代,不會有異常拋出 # 需要新建一個,因為上一個已經被迭代完了(生成器是一次性用品) my_gen_02 = (i*2 for i in range(10))for val in my_gen_02:print(val) """ 運行結果: 0 2 4 6 8 10 12 14 16 18 """


二、用函數來實現復雜的生成器

# -*- coding:utf-8 -*- # Author: Evan Mi# 引用別人的斐波那契數列生成函數 """函數運行到yield的時候,就會暫停,并將yield關鍵字之后的值傳到函數外,函數暫停在這里,直到等到下一次迭代""" def fib(max_num):n, a, b = 0, 0, 1while n < max_num:yield ba, b = b, a+bn += 1# 定義了一個生成器,這個生成器每次迭代得到的值就是yield帶出來的值fb = fib(10)# 用for循環迭代 for val in fb:print(val) """ 運行結果: 1 1 2 3 5 8 13 21 34 55 """ # 用next迭代 fb1 = fib(10) while True:try:print(next(fb1))except StopIteration as e:print(e.value)break """ 運行結果: 1 1 2 3 5 8 13 21 34 55 None """

可以看到,在使用for循環迭代的時候,并不需要自己去處理迭代停止的異常;而用next自己處理就需要;而且

我們每次的e.value都是none;現在給函數加上返回值,如下:

def fib(max_num):n, a, b = 0, 0, 1while n < max_num:yield ba, b = b, a+bn += 1return 'done'

對這樣的函數,我們用next調用;

# 用next迭代 fb1 = fib(10) while True:try:print(next(fb1))except StopIteration as e:print(e.value)break """ 運行結果: 1 1 2 3 5 8 13 21 34 55 done """

可以看到e.value變成了done;所以一個函數如果作為了生成器,那么return的值就是迭代停止時的異常信息;


yield能帶出函數中的值,那么yield就是函數內部與外界的媒介,那么自然也能從外部代值回來:

修改函數如下:

def fib(max_num):n, a, b = 0, 0, 1while n < max_num:xxx = yield b # 后面的b在運行到yield時被帶出去,前面的xx在激活yield時被帶進來print(xxx)a, b = b, a+bn += 1return 'done'

執行如下的測試:

gx = fib(10) # 一開是只能調用next,因為這時只是創建了一個生成器,還沒有yield變量 print('out;', next(gx)) # 把233給yield,同時往下運行到下一次循環到yield處,并帶回yield的值 print('out;', gx.send(233)) print('out;', gx.send(333)) print('out;', gx.send(433)) # 循環到下一次的yield,并帶回yield的值(其實就是把None給了yield) print('out;', next(gx))

運行結果如下:

out; 1? 第一次只能從yield帶出值
233? ? 通過yield傳入了233,在函數內部打印
out; 1? ? 帶出1
333? ? 傳入333
out; 2 帶出2
433 傳入433
out; 3 帶出3
None 傳入None
out; 5 帶出5


總結

以上是生活随笔為你收集整理的python3 生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

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