迭代器、生成器

迭代器python

什麼是迭代器app

#迭代器即迭代的工具,那什麼是迭代呢?
#迭代是一個重複的過程,每次重複即一次迭代,而且每次迭代的結果都是下一次迭代的初始值
while True: #只是單純地重複,於是不是迭代
    print('===>') 
    
l=[1,2,3]
count=0
while count < len(l): #迭代
    print(l[count])
    count+=1

 

爲何要迭代器函數

#一、爲什麼要有迭代器?
對於序列類型:字符串、列表、元組,咱們可使用索引的方式迭代取出其包含的元素。
但對於字典、集合、文件等類型是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,這就是迭代器 #二、什麼是可迭代對象? 可迭代對象指的是內置有__iter__方法的對象,即obj.__iter__,以下
'hello'.__iter__
(1,2,3).__iter__
[1,2,3].__iter__
{'a':1}.__iter__
{'a','b'}.__iter__
open('a.txt').__iter__

 

#三、什麼是迭代器對象?
可迭代對象執行obj.__iter__()獲得的結果就是迭代器對象迭代器對象指的是即內置有__iter__又內置有__next__方法的對象

文件類型是迭代器對象
open('a.txt').__iter__()
open('a.txt').__next__()
#四、注意:
迭代器對象必定是可迭代對象,而可迭代對象不必定是迭代器對象

應用工具

 迭代器對象的使用spa

dic={'a':1,'b':2,'c':3}
iter_dic=dic.__iter__() #獲得迭代器對象,迭代器對象即有__iter__又有__next__,可是:迭代器.__iter__()獲得的仍然是迭代器自己
iter_dic.__iter__() is iter_dic #True

print(iter_dic.__next__()) #等同於next(iter_dic)
print(iter_dic.__next__()) #等同於next(iter_dic)
print(iter_dic.__next__()) #等同於next(iter_dic)
# print(iter_dic.__next__()) #拋出異常StopIteration,或者說結束標誌

#有了迭代器,咱們就能夠不依賴索引迭代取值了
iter_dic=dic.__iter__()
while 1:
    try:
        k=next(iter_dic)
        print(dic[k])
    except StopIteration:
        break
        
#這麼寫太醜陋了,須要咱們本身捕捉異常,控制next,python這麼牛逼,能不能幫我解決呢?能,請看for循環

for循環code

#基於for循環,咱們能夠徹底再也不依賴索引去取值了
dic={'a':1,'b':2,'c':3}
for k in dic:     #in後必定要是可迭代對象
    print(dic[k])

#for循環的工做原理
#1:執行in後對象的dic.__iter__()方法,獲得一個迭代器對象iter_dic
#2: 執行next(iter_dic),將獲得的值賦值給k,而後執行循環體代碼
#3: 重複過程2,直到捕捉到異常StopIteration,結束循環

迭代器的優缺點

#優勢:
  - 提供一種統一的、不依賴於索引的迭代方式
  - 惰性計算,節省內存
#缺點:
  - 無法獲取長度(只有在next完畢才知道到底有幾個值)
  - 一次性的,只能日後走,不能往前退

 什麼是生成器

#只要函數內部包含有yield關鍵字,那麼函數名()的到的結果就是生成器,而且不會執行函數內部代碼

def func():
    print('====>first')
    yield 1
    print('====>second')
    yield 2
    print('====>third')
    yield 3
    print('====>end')

g=func()
print(g) #<generator object func at 0x0000000002184360>

生成器本質是迭代器對象

爲何要有生成器

生成器是一種自定義迭代器的方式blog

如何用生成器

g.__iter__
g.__next__

res=next(g)

print(res)

自定義range

def my_range(start,stop,step=1):
    while start < stop:
        yield start # 暫停
        start+=step
g=my_range(1,5,2) #1 3


print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

for item in g:
    print(item)


#總結yield的功能
#一、提供一種自定義迭代器的方式
#二、yield能夠暫停住函數,返回值

#yield  VS return
#相同點:都是用在函數內,均可以返回值,沒有類型限制,沒有個數限制
#不一樣點:return只能返回一次值,yield能夠返回屢次值

瞭解索引

# 瞭解知識
# yield 值
# x=yield
# x= yield 值

def dog(name):
    food_list=[]
    print('狗哥 %s 準備開吃' %name)
    while True:
        food=yield food_list#暫停 food=yield='一桶泔水'
        print('狗哥[%s]吃了<%s>' %(name,food))
        food_list.append(food)


alex_dog=dog('alex')

res1=next(alex_dog) # 初始化,即讓狗準備好
print(res1)
# next(alex_dog) # 等同於alex_dog.send(None)
#
# next(alex_dog)

res2=alex_dog.send(('一泡翔','咖啡伴侶'))
print(res2)

res3=alex_dog.send('一桶泔水')
print(res3)
相關文章
相關標籤/搜索