首頁 >後端開發 >Python教學 >Python中迭代器和生成器的範例詳解

Python中迭代器和生成器的範例詳解

黄舟
黄舟原創
2017-08-13 10:00:141251瀏覽

迭代器


Iterable

定義

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

由定義可知Iterable必然包含# __iter__函數

Iterator

定義

class Iterator(Iterable):

    __slots__ = ()

    @abstractmethod
    def __next__(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration

    def __iter__(self):
        return self

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            if (any("__next__" in B.__dict__ for B in C.__mro__) and
                any("__iter__" in B.__dict__ for B in C.__mro__)):
                return True
        return NotImplemented

從定義可知Iterator包含#__next____iter__函數,當next超出範圍時將拋出StopIteration事件

類型關係

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

from collections import Iterator,Iterable

# 迭代器
s = 'abc'
l = [1,2,3]
d=iter(l)

print(isinstance(s,Iterable)) # True
print(isinstance(l,Iterable)) # True

print(isinstance(s,Iterator)) # False
print(isinstance(l,Iterator)) # False

print(isinstance(d,Iterable)) # True
print(isinstance(d,Iterator)) # True

理論上你可以使用next()來執行__next__(),直到迭代器拋出StopIteration 實際上系統提供了for .. in ..的方式來解析迭代器

l = [1,2,3,4]
for i in l:
    print(i)
    
# 执行结果    
# 1
# 2
# 3
# 4

生成器generator


# 生成器的本質是迭代器

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

from collections import Iterator,Iterable

s = (x*2 for x in range(5))
print(s)
print('Is Iterable:' + str(isinstance(s,Iterable)))
print('Is Iterator:' + str(isinstance(s,Iterator)))

for x in s:
    print(x)

# 执行结果    
# <generator object <genexpr> at 0x000001E61C11F048>
# Is Iterable:True
# Is Iterator:True
# 0
# 2
# 4
# 6
# 8

函數中如果存在yield 則該函數是一個生成器物件在每一次執行next函數時該函數會在上一個yield處開始執行,並在下一個yield處返回(相當於return

#
def foo():
    print("First")
    yield 1
    print("Second")
    yield 2

f = foo()
print(f)

a = next(f)
print(a)
b = next(f)
print(b)

# <generator object foo at 0x0000020B697F50F8>
# First
# 1
# Second
# 2


實例

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

def add(s,x):
    return s+x

def gen():
    for i in range(4):
        yield i

base = gen()

# 由于gen函数中存在yield,所以
# for 循环本质是创建了两个generator object,而非执行函数
# base = (add(i,10) for i in base)
# base = (add(i,10) for i in base)
for n in [1,10]:
    base = (add(i,n) for i in base)


# 这里才开始展开生成器
# 第一个生成器展开
# base = (add(i,10) for i in base)
# base = (add(i,10) for i in range(4))
# base = (10,11,12,13)
#
# 第二个生成器展开
# base = (add(i,10) for i in (10,11,12,13))
# base = (20,21,22,23)
print(list(base)) # [20,21,22,23]

以上是Python中迭代器和生成器的範例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn