1. 程式人生 > >列表生成式、生成器、叠代器。

列表生成式、生成器、叠代器。

err 需要 end 每一個 可叠代對象 生成式 ner 大量 dir

列表生成式,需求把列表[0,1,2,3,4,5,6,7,8,9]每一個元素加1。

#列表生成式  list generration
#第一種方法
a = [0,1,2,3,4,5,6,7,8,9]
b = []
for i in a:
    b.append(i+1)

print(b)

#第二種方法
c = [i+1 for i in a]
print(c)

#第三種方法
for index,i in enumerate(a):
    a[index] +=1

print(a)


#通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,
不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那後面絕大多數元素占用的空間都白白浪費了。
 

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

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

L = [i*2 for i in range(10)]  #列表生成式
print(L)

g = (i*2 for i in
range(10)) #創建一個生成器,僅僅把列表中括號改成小括號。 print(g) g.__next__()

1、生成器只有在調用的時候才會產生數據。

2、生成器取值只能往後取值,不能跨步取值和後退取值。

g = (i*2 for i in range(10))  #創建一個生成器,僅僅把列表中括號改成小括號。

print(g.__next__()) #一般不采用此種方法進行調用,如果調用值超過了生成器的值那麽分出現報錯。
for n in g:     #使用for循環進行調用並且不會出現超出值而報錯。
    print(n)

我們創建了一個generator後,基本上永遠不會調用next()

,而是通過for循環來叠代它,並且不需要關心StopIteration的錯誤。

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

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

def fib(max):
    n,a,b, = 0,0,1
    while n <max:
        #print(b) #這種方式還不叫生成器,距離生成器只有一步之遙了。
        yield (b)
        a,b = b,a+b
        n = n+1
  returan "------none-----"
g = fib(10) #給以給生成器賦值進行調用。 for i in g: print(i)

技術分享

如果執行報StopIteration可以用下面這段代碼進行抓錯。

while True:
    try:
        x =next(g)  #此處會去調用生成器一直調用到出錯會被下面的except給抓到
        print("g",x) 
    except StopIteration as e:   #只有當報StopIteration  as(賦名)給 e 
        print("Generrator return value",e.value)
        break

叠代器

可以直接作用於for循環的數據類型有以下幾種:

一類是集合數據類型,如listtupledictsetstr等;

一類是generator,包括生成器和帶yield的generator function。

這些可以直接作用於for循環的對象統稱為可叠代對象:Iterable

可以使用isinstance()判斷一個對象是否是Iterable對象:.

a = [1,2,3]
print(dir(a)) #用內置函數可以查看可用的調用方式。
 
from collections import Iterable #判斷是否為叠代器對象

print(isinstance([],Iterable))  #判斷是否為叠代器對象
#輸出結果
True
print(isinstance([-1,0,1],Iterable))#判斷是否為叠代器對象
#輸出結果
True
print(isinstance(0,Iterable))#判斷是否為叠代器對象
#輸出結果
False

from collections import Iterator    #判斷是否為叠代器
print(isinstance([x for x in range(5)],Iterator))   #判斷是否為叠代器
#輸出結果
False
print(isinstance(iter([x for x in range(5)]),Iterator)) #判斷是否為叠代器
#輸出結果

列表生成式、生成器、叠代器。