真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

生成器和迭代器

1.列表生成式

現(xiàn)在有個(gè)需求,看列表[0, 1, 2, 3, 4, 5],要求你把列表里的每個(gè)值加1,你怎么實(shí)現(xiàn)?

創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司與策劃設(shè)計(jì),奉賢網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:奉賢等地區(qū)。奉賢做網(wǎng)站價(jià)格咨詢:028-86922220

可以使用for循環(huán),while循環(huán)
map方式
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a = map(lambda x:x+1, a)
>>> a

>>> for i in a:print(i)
... 
3
5
7
9
11

高級(jí)方式:
列表生成式方式
>>> a = [i+1 for i in range(10)]
>>> a
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a = [i for i in range(10)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

2.生成器

2.1生成器的創(chuàng)建與調(diào)用

通過列表生成式,我們可以直接創(chuàng)建一個(gè)列表。但是,收到內(nèi)存限制,列表容量是有限的。而且,創(chuàng)建一個(gè)包含100萬個(gè)元素的列表,不僅占用很大的存儲(chǔ)空間,如果我們僅僅使用其中的幾個(gè)元素,那后面的元素所占用的空間就浪費(fèi)掉了。
所以,如果列表中的元素可以按照某種算法推算出來,那是否可以在循環(huán)的過程中推算出后續(xù)的元素呢?就不需要?jiǎng)?chuàng)建完整的list,從而節(jié)省大量的空間。在Python中,一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器:generator.
要?jiǎng)?chuàng)建一個(gè)generator,有很多種方法。第一種方法很簡單,只要把一個(gè)列表生成式的[]改成(),就創(chuàng)建了一個(gè)generator
生成器的特性:
1.預(yù)先定義一個(gè)生產(chǎn)輸?shù)姆秶褂靡粋€(gè)生產(chǎn)一個(gè),不占用內(nèi)存空間
2.只能往下不斷取數(shù),不能回退
3.走到最后,報(bào)stopIteration錯(cuò)誤

##這里生成大量的數(shù)據(jù),需要一段時(shí)間
>>> a = [i for i in range(100000000000000)]
##列表生成式,立刻生成,因?yàn)槭钦{(diào)用net()方法時(shí)才產(chǎn)生數(shù)據(jù),調(diào)用一次產(chǎn)生一次
>>> a = (i for i in range(100000000000000))
>>> 
>>>
>>> a = [i for i in range(10)]
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> g = (i*2 for i in range(10))
>>> g
 at 0x00000237FF9BF2B0>
通過next()函數(shù)獲得generator的下一個(gè)返回值
>>> next(g)
0
>>> next(g)
2
>>> next(g)
4
>>>
>>> next(g)
16
>>> next(g)
18
>>> next(g)
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

#可使用for循環(huán)調(diào)用
#創(chuàng)建了一個(gè)generator后,基本上永遠(yuǎn)不會(huì)調(diào)用next(),而是通過for循環(huán)來迭代它,并且不需要關(guān)心StopIteration的錯(cuò)誤
>>> g = (i*2 for i in range(10))
>>> for n in g:
...     print(n)
...
0
2
4
6
8
10
12
14
16
18
>>>

2.2通過函數(shù)方式創(chuàng)建生成器

generator非常強(qiáng)大。如果推算的算法比較復(fù)雜,用類似列表生成式的for循環(huán)無法實(shí)現(xiàn)的時(shí)候,可以使用函數(shù)來實(shí)現(xiàn)

2.2.1斐波那契數(shù)列-普通函數(shù)方式

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
                # 相當(dāng)于t = a+b, a = b,b = t,但不需要顯式寫出臨時(shí)變量t就可以賦值
        a, b = b, a + b
        n = n + 1
    return 'done'
fib(10)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
1
1
2
3
5
8
13
21
34
55

Process finished with exit code 0

仔細(xì)觀察。fib函數(shù)實(shí)際上已經(jīng)定義了斐波那契數(shù)列的推算規(guī)則,可以從第一個(gè)元素開始推算出后續(xù)的任意元素,這種邏輯其實(shí)已經(jīng)很類似generator,實(shí)際只需要把print(b)改為yield b就變成了生成器。

2.2.2斐波那契數(shù)列-生成器方式

如果一個(gè)函數(shù)定義中包含yield關(guān)鍵字,那么這個(gè)函數(shù)就不再是一個(gè)普通函數(shù),而是一個(gè)generator.

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
# 用for循環(huán)輸出內(nèi)容
for i in fib(10):
    print(i)

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
1
1
2
3
5
8
13
21
34
55

Process finished with exit code 0

print(fib(10))

生成器和迭代器

普通函數(shù)是順序執(zhí)行的,遇到return語句或最后一行函數(shù)語句就返回?cái)?shù)據(jù),并凍結(jié)當(dāng)前的執(zhí)行過程
generator的執(zhí)行流程是每次調(diào)用next()的時(shí)候執(zhí)行,遇到y(tǒng)eild語句返回,再次調(diào)用next()時(shí)從上次yeild語句處繼續(xù)執(zhí)行。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
data = fib(10)
print(data.__next__())
print(data.__next__())
print("做別的事情")
print(data.__next__())
print(data.__next__())
print(data.__next__())

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
1
1
做別的事情
2
3
5

Process finished with exit code 0

用for循環(huán)調(diào)用generator時(shí),發(fā)現(xiàn)拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲StopIteration錯(cuò)誤,返回值包含在StopIteration的value中

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
g = fib(10)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
g: 13
g: 21
g: 34
g: 55
Generator return value: done

Process finished with exit code 0

2.3send

send作用
1.喚醒并繼續(xù)執(zhí)行
2.發(fā)送一個(gè)信息到生成器內(nèi)部

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita

def fib(max):
    n,a,b = 0,0,1

    while n < max:
        #print(b)
        sign=yield  b
        a,b = b,a+b
        if sign=="stop":
            print(sign)

        n += 1

    return 'done'

f = fib(6)
print(next(f))
print(next(f))
print(next(f))
f.send("stop")
print(next(f))

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
1
1
2
stop
5

2.4range和xrange

python3中
range()就是創(chuàng)建了一個(gè)生成器,用到的時(shí)候才會(huì)生成數(shù)據(jù)
Python2中
range()是創(chuàng)建一個(gè)定義大小的列表,
xrange()是創(chuàng)建了一個(gè)一個(gè)生成器,和Python3中的range()相同

>python3
Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> range(100000000000000000000)
range(0, 100000000000000000000)
>>> type(range(10))


>>> quit()

>python2
Python 2.7.16 (v2.7.16:413a49145e, Mar  4 2019, 01:37:19) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> xrange(100000000)
xrange(100000000)
>>> range(10000000)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37...]
>>> type(range(10))

>>> type(xrange(10))

3.迭代器

3.1可迭代對(duì)象

我們已經(jīng)知道,可以用于for循環(huán)的數(shù)據(jù)類型有以下幾種:
一類是集合數(shù)據(jù)類型,如list,tuple,dict,set,str等;
一類是generator,包括生成器和帶yeild的generator function。
這些可以直接作用于for循環(huán)的對(duì)象稱為可迭代對(duì)象(Iterable)
可以使用isinstance()判斷一個(gè)對(duì)象是否是Iterable對(duì)象

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

3.2迭代器

生成器不但可以用for循環(huán),還可以被next()函數(shù)不斷調(diào)用并返回下一個(gè)值,直到最后拋出StopIteration錯(cuò)誤表示無法繼續(xù)返回下一個(gè)值。
可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對(duì)象稱為迭代器(Iterator)
可以使用isinstance()判斷一個(gè)對(duì)象是否是Iterator對(duì)象

python3
>>> from collections import Iterator
 >>> isinstance(range(10),Iterator)
False

>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

生成器都是迭代器,但list,tuple,set,dict,str雖然是可迭代對(duì)象,但不是迭代器。
可以使用iter()函數(shù)把list,str,dict,set變?yōu)榈?/p>

>>> isinstance(iter([]),Iterator)
True
>>> isinstance(iter(""),Iterator)
True
>>> isinstance(iter({}),Iterator)
True
>>>

為什么list,set,dict,str不是迭代器?
因?yàn)镻ython的迭代器對(duì)象表示的是一個(gè)數(shù)據(jù)流,Iterator對(duì)象可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯(cuò)誤。可以把這個(gè)數(shù)據(jù)流看做是一個(gè)有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數(shù)實(shí)現(xiàn)按需計(jì)算下一個(gè)數(shù)據(jù),所以Iterator的計(jì)算是惰性的,只有在需要返回下一個(gè)數(shù)據(jù)時(shí)才會(huì)計(jì)算。
Iterator甚至可以表示一個(gè)無限大的數(shù)據(jù)流,例如全體自然數(shù)。而使用list是永遠(yuǎn)不可能存儲(chǔ)全體自然數(shù)的。

4.小節(jié)

1.凡是可作用于for循環(huán)的對(duì)象都是Iterable類型;
2.凡是可作用于next()函數(shù)的對(duì)象都是Iterator類型,它們表示一個(gè)惰性計(jì)算的序列;
3.集合數(shù)據(jù)類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個(gè)Iterator對(duì)象。
4.Python3的for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的,例如:

for x in [1, 2, 3, 4, 5]:
    pass
實(shí)際上完全等價(jià)于:

# 首先獲得Iterator對(duì)象:
it = iter([1, 2, 3, 4, 5])
# 循環(huán):
while True:
    try:
        # 獲得下一個(gè)值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循環(huán)
        break

本文題目:生成器和迭代器
網(wǎng)站網(wǎng)址:http://weahome.cn/article/pjcjjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部