第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Python 進(jìn)階應(yīng)用教程

Python 進(jìn)階應(yīng)用教程
01 Python 的對(duì)象和類 02 Python 類屬性和實(shí)例屬性 03 Python類的構(gòu)造方法、析構(gòu)方法、實(shí)例方法 04 Python 類的私有屬性和私有方法 05 Python 類的繼承和多繼承 06 Python 類實(shí)戰(zhàn) 07 Python 中的迭代器實(shí)現(xiàn)原理 08 Python 中的迭代器趣味實(shí)踐 09 Python 中的生成器實(shí)現(xiàn)原理 10 Python 中的生成器趣味實(shí)踐 11 Python 中的錯(cuò)誤和異常 12 Python 中的異常處理 13 Python 中的模塊 14 Python 標(biāo)準(zhǔn)庫之 os 模塊 15 Python 標(biāo)準(zhǔn)庫之 sys 模塊 16 Python 標(biāo)準(zhǔn)庫之 math 模塊 17 Python 標(biāo)準(zhǔn)庫之 random 模塊 18 Python 標(biāo)準(zhǔn)庫之 Json 模塊 19 Python 標(biāo)準(zhǔn)庫 datetime 模塊 20 Python 中的常用第三方模塊 21 Python 中的命名空間 22 Python 中的作用域 23 Python 中的文件 IO 操作 24 Python 基礎(chǔ)實(shí)戰(zhàn) 25 Python 內(nèi)置函數(shù) 26 Python 中使用正則表達(dá)式 27 使用 Python 操作 MySQL 數(shù)據(jù)庫 28 使用 Python 操作 Mongo 數(shù)據(jù)庫 29 使用 Python 操作 Redis 數(shù)據(jù)庫 30 使用 Python 發(fā)送一封郵件 31 threading 之 Thread 的使用 32 threading 之 Lock 的基本使用 33 Python 生產(chǎn)者消費(fèi)者模型 34 Python 的內(nèi)存管理與垃圾回收 35 Python 領(lǐng)域運(yùn)用:網(wǎng)絡(luò)爬蟲 36 Python 領(lǐng)域運(yùn)用:Web 開發(fā) 37 Python 領(lǐng)域運(yùn)用:自動(dòng)化運(yùn)維 38 Python 領(lǐng)域運(yùn)用:自動(dòng)化測(cè)試

Python 中的迭代器實(shí)現(xiàn)原理

在數(shù)學(xué)中,集合表示由一個(gè)或多個(gè)確定的元素所構(gòu)成的整體。在 Python 中,列表、元組、集合可以用于表示數(shù)學(xué)中的集合。

例如,分別使用列表、元組、集合表示了一個(gè)包含 3 個(gè)字符串的集合:

  • 列表 [‘www’, ‘imooc’, ‘com’]
  • 元組 (‘www’, ‘imooc’, ‘com’)
  • 集合 {‘www’, ‘imooc’, ‘com’}

1. 可迭代對(duì)象 iterable

1.1 什么是可迭代對(duì)象

Python 提供了 for … in 循環(huán),用于對(duì)列表、元組、集合中的元素進(jìn)行遍歷。能夠被 for … in 循環(huán)遍歷的對(duì)象被稱為可迭代對(duì)象 iterable,列表、元組、集合均屬于可迭代對(duì)象。使用 for … in 循環(huán)遍歷可迭代對(duì)象的例子如下:

  • 遍歷列表的代碼
list = ['www', 'imooc', 'com']
for item in list:
    print(item)
  • 遍歷元組的代碼
tuple = ('www', 'imooc', 'com')
for item in tuple:
    print(item)
  • 遍歷集合的代碼
set = {'www', 'imooc', 'com'}
for item in set:
    print(item)

1.2 盡可能使用 for … in 循環(huán)進(jìn)行遍歷

如果需要遍歷的對(duì)象是列表,可以通過訪問索引的方式進(jìn)行遍歷,代碼如下:

strings = ['www', 'imooc', 'com']
i = 0
while i < len(strings):
    string = strings[i]
    print(string)
    i = i + 1
  • 在第 1 行,使用列表表示 strings
  • 在第 3 行,通過 len(strings) 獲取列表 strings 中字符串的數(shù)量
  • 在第 4 行,通過 strings[i] 訪問第 i 個(gè)元素

以上的遍歷方式中,要求 strings 是一個(gè)列表,如果 strings 的數(shù)據(jù)結(jié)構(gòu)發(fā)生變化:使用集合而不是列表表示 strings,那么通過訪問索引的方式進(jìn)行遍歷的代碼就會(huì)失效。

strings = {'www', 'imooc', 'com'}
i = 0
while i < len(strings):
    string = strings[i]
    print(string)
    i = i + 1
  • 在第 1 行,使用集合表示 strings
  • 在第 3 行,通過 len(strings) 獲取集合 strings 中字符串的數(shù)量
  • 在第 4 行,通過 strings[i] 訪問第 i 個(gè)元素

因?yàn)?strings 是一個(gè)集合,不支持索引操作,會(huì)導(dǎo)致運(yùn)行錯(cuò)誤:

Traceback (most recent call last):
  File "strings.py", line 5, in <module>
    string = strings[i]
TypeError: 'set' object does not support indexing

應(yīng)盡可能使用 for … in 循環(huán)遍歷可迭代對(duì)象,如果可迭代對(duì)象的數(shù)據(jù)類型發(fā)生變化,從列表變成集合,使用for … in 循環(huán)遍歷的代碼則無需改變。

2. 迭代器 iterator

1.1 什么是迭代器

迭代器 iterator 是一個(gè)特殊的對(duì)象,用于遍歷訪問可迭代對(duì)象 iterable。Python 通過迭代器 iterator 實(shí)現(xiàn) for … in 循環(huán)語句,用戶編寫的 for … in 循環(huán)代碼如下:

for item in iterable:
    print(item)

這段 for … in 循環(huán)代碼會(huì)被翻譯為如下:

iterator = iter(iterable)
while True:
    try:
        item = next(iterator)
        print(item)
    except StopIteration:
        break
  • 在第 1 行,內(nèi)置函數(shù) iter 獲取可迭代對(duì)象 iterable 的迭代器 iterator
  • 在第 4 行,內(nèi)置函數(shù) next 獲取迭代器 iterator 返回的下一個(gè)元素
  • 在第 6 行,當(dāng)?shù)鞅闅v完全部元素后,拋出一個(gè)特殊的異常 StopIteration,表示迭代結(jié)束

1.2 列表的迭代器

下面通過一個(gè)具體的例子,了解如何通過迭代器實(shí)現(xiàn) for … in 循環(huán),使用 for … in 循環(huán)遍歷列表的代碼如下:

list = ['www', 'imooc', 'com']
for item in list:
    print(item)

Python 把以上 for … in 循環(huán)轉(zhuǎn)換為如下功能等價(jià)的代碼:

list = ['www', 'imooc', 'com']
listIterator = iter(list)
while True:
    try:
        item = next(listIterator)
        print(item)
    except StopIteration:
        break

以上兩段代碼均輸出相同的結(jié)果,如下所示:

www
imooc
com

3. 迭代協(xié)議

使用迭代器遍歷訪問可迭代對(duì)象,要求迭代器和可迭代對(duì)象遵循迭代協(xié)議,迭代協(xié)議如下:

  1. 可迭代對(duì)象 iterable 提供成員方法 __iter__,該方法返回用于遍歷的迭代器 iterator
class Iterable:
    def __iter__(self):
  1. 迭代器 iterator 提供成員方法 __next__,該方法返回下一個(gè)被遍歷的元素
class Iterator:
    def __next__(self):
  1. 異常 StopIteration,當(dāng)遍歷完全部的元素后,成員方法 __next__ 拋出一個(gè)特殊的異常 Stop Iteration 表示遍歷結(jié)束

  2. 內(nèi)置函數(shù) iter,用于獲取可迭代對(duì)象對(duì)應(yīng)的迭代器

def iter(iterable):
    iterator = iterable.__iter__()
    return iterator
  • 在第 1 行,iter 的輸入?yún)?shù)是可迭代對(duì)象 iterable
  • 在第 2 行,調(diào)用成員方法 __iter__
  • 在第 3 行,返回迭代器 iterator
  1. 內(nèi)置函數(shù) next,用于獲取下一個(gè)被遍歷的元素
def next(iterator):
    item = iterator.__next__()
    return item
  • 在第 1 行,next 的輸入?yún)?shù)是迭代器 iterator
  • 在第 2 行,調(diào)用成員方法 __next__
  • 在第 3 行,返回被遍歷的元素

根據(jù)以上的迭代協(xié)議,即可將 for … in 循環(huán)翻譯為如下等價(jià)代碼:

iterator = iter(iterable)
while True:
    try:
        item = next(iterator)
        print(item)
    except StopIteration:
        break

4. 實(shí)現(xiàn)一個(gè)自定義的迭代器

4.1 通過單鏈表實(shí)現(xiàn)堆棧

通過單鏈表實(shí)現(xiàn)堆棧,圖示如下:
圖片描述

通過單鏈表實(shí)現(xiàn)堆棧

在上圖中,每個(gè)節(jié)點(diǎn)有兩個(gè)字段: item 和 next,item 用于存儲(chǔ)數(shù)據(jù),next 指向下一個(gè)節(jié)點(diǎn),head 指針指向堆棧的頂部。描述堆棧的 Python 代碼如下:

class Node:
    def __init__(self, item):
        self.item = item
        self.next = None

class Stack:
    def __init__(self):
        self.head = None

    def push(self, item):
        node = Node(item)
        node.next = self.head
        self.head = node

stack = Stack()
stack.push('a')
stack.push('b')
stack.push('c')
  • 在第 1 行,定義了類 Node 用于描述鏈表中的節(jié)點(diǎn)
  • 在第 6 行,定義了類 Stack 描述堆棧
    • 在第 8 行,定義了頭指針 head,指向鏈表中的首個(gè)節(jié)點(diǎn)
    • 在第 10 行,定義了成員方法 push,將元素壓如到堆棧中
      • 在第 11 行,創(chuàng)建一個(gè)新節(jié)點(diǎn) node
      • 在第 12 行,新節(jié)點(diǎn) node 的 next 指向頭結(jié)點(diǎn)
      • 在第 13 行,頭結(jié)點(diǎn)指向新節(jié)點(diǎn)
  • 在第 15 行,創(chuàng)建一個(gè)對(duì)象 stack
  • 在第 16 行到第 18 行,依次壓入 3 個(gè)元素 ‘a(chǎn)’、‘b’、‘c’

4.2 實(shí)現(xiàn)迭代協(xié)議

class StackIterator:
    def __init__(self, stack):
        self.stack = stack
        self.cursor = self.stack.head

    def __next__(self):
        if self.cursor == None:
            raise StopIteration
        else:
            item = self.cursor.item
            self.cursor = self.cursor.next
            return item
  • 在第 1 行,定義類 StackIterator
    • 類 Stack 是可迭代對(duì)象
    • 類 StackIterator 是迭代器
  • 在第 2 行,定義構(gòu)造函數(shù),參數(shù) stack 是被遍歷的對(duì)象
    • 在第 4 行,成員變量 cursor 指向了當(dāng)前正在遍歷的元素,初始化被設(shè)置為鏈表的頭結(jié)點(diǎn)
  • 在第 6 行,定義方法 __next__
    • 在第 7 行,如果變量 cursor 等于 None,表示已經(jīng)到達(dá)鏈表的尾部,即遍歷完全部的元素了
      • 在第 8 行,拋出異常 StopIteration 表示遍歷結(jié)束
    • 在第 9 行,如果變量 cursor 不等于 None
      • 在第 10 行,記錄下當(dāng)前正在遍歷的元素
      • 在第 11 行,將 cursor 指向下一個(gè)元素

在定義了 StackIterator 后,在 Stack 中增加一個(gè)新的成員方法 __iter__,返回 Stack 對(duì)應(yīng)的迭代器,代碼如下:

class Stack:
    def __iter__(self):
        return StackIterator(self)   

4.3 通過 while 循環(huán)遍歷堆棧

在實(shí)現(xiàn)了迭代協(xié)議后,使用 while 循環(huán)顯示的使用 iter、next、StopIteration 完成對(duì) stack 的遍歷,代碼如下:

stackIterator = iter(stack)
while True:
    try:
        item = next(stackIterator)
        print(item)
    except StopIteration:
        break

程序依次壓入 ‘a(chǎn)’、‘b’、‘c’,遍歷時(shí)以壓入相反的順序輸出,結(jié)果如下:

c
b
a

4.4 通過 for … in 循環(huán)遍歷堆棧

在實(shí)現(xiàn)了迭代協(xié)議后,可以通過 for … in 循環(huán)進(jìn)行遍歷,代碼如下:

for item in stack:
    print(item)

與上一節(jié)的代碼相比,代碼要簡(jiǎn)潔很多,程序輸出相同的結(jié)果如下:

c
b
a