1. 程式人生 > >python學習第十三天 叠代器 生成器

python學習第十三天 叠代器 生成器

opened 對象 info 生成 位置參數 分享圖片 自定義 器協 但是

1.函數復習總結

技術分享圖片
# 函數 —— 2天
    # 函數的定義和調用
    # def 函數名(形參):
        #函數體
        #return 返回值
    #調用 函數名(實參)
    # 站在形參的角度上 : 位置參數,*args,默認參數(陷阱),**kwargs
    # 站在實參的角度上 : 按照位置傳,按照關鍵字傳
    # 返回值:沒有返回值 返回一個值 返回多個值
    # 接收返回值:沒有返回值不接收,返回一個值用一個變量接收,返回多個值用一個變量或者對應數目的變量接收
# 閉包函數 —— 在內部函數引用外部函數的變量
# 裝飾器函數—— 裝飾器一定是閉包函數
# 裝飾器的作用 : 在不改變原來函數的調用方式的情況下 在這個函數的前後添加新的功能 # 完美的符合了一個開發原則 :開放封閉原則 # 對擴展是開發的 # 對修改是封閉的 # 基礎的裝飾器 # from functools import wraps # def wrapper(func): # @wraps(func) # def inner(*args,**kwargs): # ‘‘‘在函數被調用之前添加的代碼‘‘‘ #
ret = func(*args,**kwargs) # func是被裝飾的函數 在這裏被調用 # ‘‘‘在函數被調用之後添加的代碼‘‘‘ # return ret # return inner # 使用 —— @wrapper # @wrapper # def func(): #inner # pass # # func.__name__ # 帶參數的裝飾器 #
@wrapper -- > @warapper(argument) # 三層嵌套函數 # def outer(形參): # def wrapper(func): # def inner(*args,**kwargs): # ‘‘‘在函數被調用之前添加的代碼‘‘‘ # ret = func(*args,**kwargs) # func是被裝飾的函數 在這裏被調用 # ‘‘‘在函數被調用之後添加的代碼‘‘‘ # return ret # return inner # return wrapper # @outer(True) # def func(): # pass # 多個裝飾器裝飾一個函數 # 俄羅斯套娃 #def wrapper1(func): # @wraps(func) # def inner(*args,**kwargs): # print(‘before 1‘) # print(‘******‘) # ret = func(*args,**kwargs) # func是被裝飾的函數 在這裏被調用 # ‘‘‘在函數被調用之後添加的代碼‘‘‘ # return ret # def wrapper2(func): # @wraps(func) # def inner(*args,**kwargs): # print(‘before 2‘) # ret = func(*args,**kwargs) # func是被裝飾的函數 在這裏被調用 # ‘‘‘在函數被調用之後添加的代碼‘‘‘ # return ret # @wrapper1 # @wrapper2 # def func(): # print(‘111‘) # 叠代器和生成器 —— 兩天 # 內置函數 —— 兩天
View Code

2.可叠代及可叠代協議

假如我現在有一個列表l=[‘a‘,‘b‘,‘c‘,‘d‘,‘e‘],我想取列表中的內容,有幾種方式?

首先,我可以通過索引取值l[0],其次我們是不是還可以用for循環來取值呀?

你有沒有仔細思考過,用索引取值和for循環取值是有著微妙區別的。

如果用索引取值,你可以取到任意位置的值,前提是你要知道這個值在什麽位置。

如果用for循環來取值,我們把每一個值都取到,不需要關心每一個值的位置,因為只能順序的取值,並不能跳過任何一個直接去取其他位置的值。

但你有沒有想過,我們為什麽可以使用for循環來取值?

for循環內部是怎麽工作的呢?

要了解for循環是怎麽回事兒,咱們還是要從代碼的角度出發。

首先,我們對一個列表進行for循環。

for i in [1,2,3,4]:  
    print(i)

上面這段代碼肯定是沒有問題的,但是我們換一種情況,來循環一個數字1234試試

for i in 1234
    print(i) 

結果:
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    for i in 1234:
TypeError: ‘int‘ object is not iterable

看,報錯了!報了什麽錯呢?“TypeError: ‘int‘ object is not iterable”,說int類型不是一個iterable,那這個iterable是個啥?

技術分享圖片

假如你不知道什麽是iterable,我們可以翻翻詞典,首先得到一個中文的解釋,盡管翻譯過來了你可能也不知道,但是沒關系,我會帶著你一步一步來分析。

叠代和可叠代協議 什麽叫叠代 現在,我們已經獲得了一個新線索,有一個叫做“可叠代的”概念

首先,我們從報錯來分析,好像之所以1234不可以for循環,是因為它不可叠代。那麽如果“可叠代”,就應該可以被for循環了。

這個我們知道呀,字符串、列表、元組、字典、集合都可以被for循環,說明他們都是可叠代的

我們怎麽來證明這一點呢?

from collections import Iterable
                             
l = [1,2,3,4]                
t = (1,2,3,4)                
d = {1:2,3:4}                
s = {1,2,3,4}                
                             
print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))

結合我們使用for循環取值的現象,再從字面上理解一下,其實叠代就是我們剛剛說的,可以將某個數據集內的數據“一個挨著一個的取出來”,就叫做叠代

可叠代協議

可以被叠代要滿足的要求就叫做可叠代協議。可叠代協議的定義非常簡單,就是內部實現了__iter__方法。

3.叠代器

技術分享圖片
 叠代器的概念
# 叠代器協議 —— 內部含有__next__和__iter__方法的就是叠代器

# 叠代器協議和可叠代協議
# 可以被for循環的都是可叠代的
# 可叠代的內部都有__iter__方法
# 只要是叠代器 一定可叠代
# 可叠代的.__iter__()方法就可以得到一個叠代器
# 叠代器中的__next__()方法可以一個一個的獲取值

# for循環其實就是在使用叠代器
# iterator
# 可叠代對象
# 直接給你內存地址
# print([].__iter__())
# print(range(10))

#for
#只有 是可叠代對象的時候 才能用for
#當我們遇到一個新的變量,不確定能不能for循環的時候,就判斷它是否可叠代

# for i in l:
#     pass
#iterator = l.__iter__()
#iterator.__next__()

#叠代器的好處:
    # 從容器類型中一個一個的取值,會把所有的值都取到。
    # 節省內存空間
        #叠代器並不會在內存中再占用一大塊內存,
            # 而是隨著循環 每次生成一個
            # 每次next每次給我一個
# range
# f
# l = [1,2,3,45]
# iterator = l.__iter__()
# while True:
#     print(iterator.__next__())

# print(range(100000000000000))
# print(range(3))
# print(list(range(3)))
# def func():
#     for i in  range(2000000):
#         i = ‘wahaha%s‘%i
#     return i

# 生成器 —— 叠代器
# 生成器函數 —— 本質上就是我們自己寫得函數
# 生成器表達式
l = [1,2,3,4,5]
for i in l:
    print(i)
    if i == 2:
        break

for i in l:
    print(i)
View Code

4.生成器

我們知道的叠代器有兩種:一種是調用方法直接返回的,一種是可叠代對象通過執行iter方法得到的,叠代器有的好處是可以節省內存。

如果在某些情況下,我們也需要節省內存,就只能自己寫。我們自己寫的這個能實現叠代器功能的東西就叫生成器。

Python中提供的生成器:

1.生成器函數:常規函數定義,但是,使用yield語句而不是return語句返回結果。yield語句一次返回一個結果,在每個結果中間,掛起函數的狀態,以便下次重它離開的地方繼續執行

2.生成器表達式:類似於列表推導,但是,生成器返回按需產生結果的一個對象,而不是一次構建一個結果列表

生成器Generator:

  本質:叠代器(所以自帶了__iter__方法和__next__方法,不需要我們去實現)

  特點:惰性運算,開發者自定義

技術分享圖片代碼

python學習第十三天 叠代器 生成器