首頁  >  文章  >  後端開發  >  寫給Python程式設計高手2:迭代器

寫給Python程式設計高手2:迭代器

coldplay.xixi
coldplay.xixi轉載
2020-11-04 17:19:112009瀏覽

python教學專欄介紹程式設計用到的迭代器。

寫給Python程式設計高手2:迭代器

相關免費學習推薦:python教學(影片)

如何實作可迭代物件和迭代器物件

迭代器模式是一種經典的軟體設計模式,現在許多程式語言都內建了這種設計模式。在Python的原始資料類型中,可以進行for迴圈的都屬於可迭代的類型。當然,也可以使用iter函數取得到對應的迭代器,然後遍歷該物件。如下面的程式碼:

l = [1, 3]  # 可迭代对象 __iter__t = iter(l) #获取迭代器对象print(t.__next__())
print(t.__next__())# print(t.__next__()) # 报异常复制代码

要實作一個可迭代對象,一般先要實作對應的迭代器對象。在Python實作迭代器,其實只需要實作__next__方法。但collections套件中的Iterator類別將__next__方法定義為了抽象方法,筆者認為鑑於程式的可讀性,在實作迭代器時不妨繼承Iterator類別。

from random import samplefrom collections import Iterable, Iteratorclass WeatherIterator(Iterator):
    def __init__(self, cities):
        self.cities = cities
        self.index = 0

    def getWeather(self, city):
        return (city, sample(['sun','wind','yu'], 1)[0])    def __next__(self):
        if self.index == len(self.cities):            raise StopIteration
        city = self.cities[self.index]
        self.index += 1
        return self.getWeather(city)复制代码

實作可迭代的對象,也只要實作__iter__方法即可,同樣的,collections套件中的Iterable類別也將__iter__方法定義為抽象類別。

from collections import Iterableclass WeatherIterable(Iterable):
    def __init__(self, cities):
        self.cities = cities
        self.index = 0

    def __iter__(self):
        return WeatherIterator(self.cities)复制代码

這樣就可以使用for迴圈來迭代了。

for weather in WeatherIterable(['北京', '上海', '广州']):
    print(weather)复制代码

生成器簡介

先看如下程式碼:

def gen():
    print("step 1")    yield 1
    print("step 2")    yield 2
    print("step 3")    yield 3复制代码

上面的gen函數的回傳值就是一個生成器物件。

g = gen()
g.__next__()
print(g.__next__())
print(g.__next__())复制代码

如上述程式碼,每呼叫一次生成器的__next__方法,它都會執行一段gen函數,遇到yield關鍵字為止,並傳回其後的東西。因此,生成器可以理解為一種能夠被打斷的函數。

注意:生成器物件也是可迭代的物件。

for x in g:
    print(x)复制代码

如何使用生成器函數實作可迭代物件

將__iter__方法實作為生成器函數,就可以實作可迭代物件。

class PrimeNumbers:
    def __init__(self, start, end):
        self.start = start
        self.end = end    def isPrimeNum(self, k):  #判断是否是素数
        if k < 2:            return False
        for i in range(2, k):            if k % i == 0:                return False
        return True

    def __iter__(self):
        for k in range(self.start, self.end + 1):            if self.isPrimeNum(k):                yield kfor num in PrimeNumbers(2, 100):
    print(num)复制代码

如何進行反向迭代以及如何實現反向迭代

iter函數可以取得可迭代物件的正向迭代器,reversed函數則可以取得可迭代物件的反向迭代器。

l = [1, 2, 3, 4, 5]for x in reversed(l):
    print(x)复制代码

要實作反向迭代,實作__reversed__方法即可。

class FloatRange:
    def __init__(self, start, end, step=0.1):
        self.start = start
        self.end = end
        self.step = step    def __iter__(self):
        t = self.start        while t <= self.end:            yield t
            t += self.step    def __reversed__(self):
        t = self.end        while t >= self.start:            yield t
            t -= self.stepfor x in FloatRange(1.0, 4.0, 0.5):
    print(x)for x in reversed(FloatRange(1.0, 4.0, 0.5)):
    print(x)复制代码

如何對迭代器做切片操作

itertools套件中的islice函數,可以可迭代物件進行切片操作。

from itertools import islicefor x in islice(FloatRange(1.0, 4.0, 0.5), 2, 5):
    print(x)复制代码

如何在一個for語句中迭代多個可迭代物件

使用zip方法,將對應元素組成一個元組。

for w, e, m in zip([1, 2, 3, 4], ('a', 'b', 'c','d'), [5, 6, 7, 8]):
    print(w, e, m)复制代码

使用itertools套件中的chain函數,將多個可迭代物件串聯起來。 使用zip方法,將對應元素組成一個元組。

from itertools import chainfor x in chain([1, 2, 3, 4], ('a', 'b', 'c','d')):
    print(x)复制代码

以上是寫給Python程式設計高手2:迭代器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除