迭代器以及生成器

一:迭代器:

【1】ide

迭代概念:函數

(1)便是重複的過程spa

(2)每次迭代的結果都是下次迭代的初始值code

例如:對象

# PS:不是跌代的過程 雖然重複 可是每次迭代都是以單獨的不是以上次的值做爲初始值
n = 0
while True:
    print(n)

# PS:迭代
number = [1,2,3,4]
conut = 0
while conut < len(l):
        print(conut)
        conut+=1  

 

【2】blog

(1)迭代的做用:索引

  (1)對於字符串 列表 元組能夠經過索引取值內存

  (2)字典 集合 文件類型不支持索引取值 能夠經過迭代對其進行取值utf-8

 

(2) 可迭代對象:字符串

定義:內置有__iter__,能夠稱之爲可迭代對象

例如:

n = 1                                                               # 不支持__iter__、

name = 'Hello world'     .__iter__()                                # 支持__iter__

number = [1,2,3,4]    .__iter__()                                   # _支持__iter__

user_info = {'name':'SR','age':18}.__iter__()                        # 支持__iter__

s = (1,23,34,56).__iter__()                                         # 支持__iter__

f = {1,2,3,4,} .__iter__()                                          #支持__iter__

file = open('test.txt','w',encoding='utf-8').__iter__()             # 支持__iter__
可迭代對象

總結:字符串 列表 字典 集合 元組 文件

 

(3)迭代器對象:

定義:

  (1)內置有__iter__ 

  (2)內置有__next__, 能夠稱之爲迭代器對象

PS:迭代器對象必定是可迭代對象 可迭代對象不必定是迭代器對象

 

取值:

基本定義方式:變量名.__next__用來進行取值

例如:

number = [1,2,3,4]
res = number.__iter__() # 變成可迭代對象
print(res)              # <list_iterator object at 0x00000000022F7358> 取出來一串地址 若是須要取值的時候 經過該地址取值
print(res.__next__())   # 1 取值一次給一個
print(res.__next__())   # 2
print(res.__next__())   # 3
print(res.__next__())   # 4
print(res.__next__())   # StopIteration 沒有值能夠被取

PS:

(1)若是當值被取盡 會報錯由於沒有值能夠被取了

(2)迭代器對象不管執行多少次__iter__方法獲得的仍是迭代器對象自己

 

(5)迭代取值的優勢:

  (1)優勢:

      不依賴索引取值

      只返回一個生成器地址 不佔內存空間

  (2)缺點:

      不能取指定的元素

      取值完畢會報錯

      只能從前日後取 

     

(5)for循環本質:

基本定義方式:for 變量名 in 可迭代對象

內部本質:

(1)in後面調用__iter__將其後面的參數轉換成可迭代對象

(2)調用__next__用來進行取值

(3)內部若是異常 (即值被取盡)會報StopIteration 此時__next__會自動結束循環

例如:

number = [1,2,3,4]
res = number.__iter__() # 變成可迭代對象


print(res)              
print(res.__next__())   
print(res.__next__())   
print(res.__next__())   
print(res.__next__())   


while True:
    try:
        print(res.__next__())
    except StopIteration:       # 匹配出報錯的信息 當取值結束的時候會提醒
        print('值已被取盡')
        break
異常解決方法

 

二:生成器

(1)概念:用戶本身的定義的迭代器 

 

(2)生成器定義方式:

  (1)包含關鍵字yield

  (2)調用生成器 可是不會執行生成器代碼

例如:

  

def func():
    print('生成器')
    yield                # 生成器定義關鍵字
res = func()             # 調用生成器 返回地址

 

(3)生成器取值:

取值與迭代器同樣:

例如:

def func():
    print('生成器')
    yield                # 生成器定義關鍵字
res = func()             # 調用生成器 返回地址
res.__next__()          # 生成器

 

(4)生成器返回值

  (1)默認狀況下返回None

  ( 2)手工指定返回元組

# PS:返回值爲空
def func():
    print('生成器')
    yield        # 不攜帶值
res = func()
print(res.__next__()) # None

# 攜帶返回值
def func():
    print('生成器')
    yield 66,88       # 不攜帶值
res = func()
print(res.__next__()) # (66, 88)

小練習:自定義一個range的生成器

例如:

def func(start,end,step = 1): # 定義range的開頭,結尾,步長
    while start < end:
        yield start
        start += step
for i in func(1,10):
    print(i)

 

(5)yield支持爲其傳參:

例如:

def dog(name):
    print('%s 準備開吃'%name)
    while True:
        food = yield
        print('%s 吃了 %s'%(name,food))

 

(6)yield的特色:

  (1)當函數被調用的時候 其會將函數轉換成生成器

  (2)當調用到yield的時候 函數不會被關閉

  (3)有返回值

 

(7)yield 與return的異同:

  (1)相同點:

      均可以返回值 且能夠返回多個值

  (2)不一樣點:

      yield所屬的函數當執行到函數的時候能夠被屢次調用 而retrun會將函數結束

      yield能夠接受外部傳值

 

(8)生成器表達式:

  例如:

number = (i for i in range(1,10) if i !=4)
res = number
print(res)             # <generator object <genexpr> at 0x00000000020FDFC0>
print(res.__next__())  # 1

PS:

(1)生成器不會主動執行代碼

(2)必須經過調用__next__從地址中取值  

相關文章
相關標籤/搜索