python--生成器

生成器python

 


 

1、概念算法

  python中的生成器(generator)保存的是算法,只有當真正調用須要的值的時候纔會去計算出值。它是一種惰性計算(lazy evaluation)。函數

 

2、列表生成式lua

定義一個列表spa

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

除了上面直接定義外,咱們還可使用列表生成式:blog

a = [i for i in range(10)]
print(a)

#輸出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  

3、生成器內存

  經過上面的列表生成式,咱們能夠直接建立一個列表。可是受到內存的限制,列表的容量是有限的。並且若是咱們建立了一個包含數百萬元素的列表,而且只須要用到前面幾個元素,那就有大部分空間浪費了。generator

  因此,若是列表元素能夠按照某種算法推算出來,那咱們是否能夠在循環的過程當中不斷的推算後續的元素?這樣就沒必要建立完整的list,從而節省大量的空間。在pyhong中,一邊循環一邊計算的機制,稱爲生成器:generator。io

  要建立一個generator有不少種方法,咱們能夠直接將列表生成式改爲生成器:class

>>> a = (i for i in range(10))
>>> a
<generator object <genexpr> at 0x0000024897F6B4C0>

 

3.1 列表生成式和生成器

a = (i for i in range(100000000))

b = [i for i in range(100000000)]

  a的生成時間是瞬時的,而且不會佔用什麼內存空間。由於生成器根本就沒有生成所需的內容,只有在訪問的時候纔會生成相應的值

 

3.2 訪問生成器

  • 生成器只保留當前位置的值,直接訪問 a[5]是沒有值的(報錯)
  • 只有一個__next()__方法
  • 只能一個一個取值,而且只能日後取值,不能返回取前面的值

使用循環來取值:

a = (i for i in range(10))
for i in a:
    print(i)

#輸出
0
1
2
3
4
5
6
7
8
9

  

使用__next()__方法取值:

a = (i for i in range(10))
print(a.__next__())
print(a.__next__())
print(a.__next__())
print("插入")
print(a.__next__())
print(a.__next__())

#輸出
0
1
2
插入
3
4

  每調用一個__next()__方法,咱們就能取到一個值,而且咱們只能日後取值。生成器能記住當前位置的值,可是並不知道先後位置的值,這也是生成器可以節省內存的緣由。只有調用到該位置時纔會生成相應的數據。

 

4、yield將函數轉換成生成器

  利用列表只能實現一部分的功能,一下複雜的運行就不能經過列表生成式這樣的來實現了。可是咱們能夠將一個函數變成生成器。

斐波那契函數:

def fib(n):
    a = 1
    b = 1
    number = 0
    while number < n:
        print(b)
        a,b = b,a+b
        number += 1

將該函數變成生成器只須要將print(b) 改成 yield b

def fib(n):
    a = 0
    b = 1
    number = 0
    while number < n:
        #print(b)
        yield b
        a,b = b,a+b
        number += 1

f = fib(10)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())

#輸出
1
1
2
3

  

5、生成器結束

  生成器不會把結果保存在一個系列中,而是保存生成器的狀態,在每次進行迭代時返回一個值,直到遇到StopIteration異常結束。

def fib(n):
    a = 0
    b = 1
    number = 0
    while number < n:
        #print(b)
        yield b
        a,b = b,a+b
        number += 1
    return '--done--'

f = fib(6)
while True:
    try:
        x = next(f)
        print(x)
    except StopIteration as e:
        print('Generator return value:',e.value)
        break

#輸出
1
1
2
3
5
8
Generator return value: --done--
相關文章
相關標籤/搜索