Python 基础合集14:迭代器和生成器

一、前言

本小节简单介绍了生成器和迭代器的工作机制和常见形式。

环境说明:Python 3.6、windows11 64位

二、生成器generator

生成器的工作机制就是边循环边计算,可以根据需要获取数据,在Python中,这种一边循环一边计算的机制,都可称为生成器。
生成器的一大优点就是即需即取,不需要占用太多的内存,避免资源浪费。

创建生成器常用两种方法:

  • 借用列表生成式
  • 采用函数+yield

2.1 借用列表生成式

该方法很简单,只要把一个列表生成式的[]改成()即可。

>>> ls = [x for x in range(3)]
>>> ls
[0, 1, 2]
>>> g = (x for x in range(3))
>>> g
<generator object <genexpr> at 0x0000020A1F3B1A50>

创建好生成器之后,我们可以通过next()函数获取生成器的下一个返回值,每执行一次返回一个,直到取完生成器数据。
注意:取完数据之后,便会报错StopIteration

>>> next(g)
0
>>> next(g)
1
>>> next(g)
2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

当然,一般获取生成器的返回值使用for循环进行遍历,而不会调用next()一个个获取。

2.2 采用函数+yield

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
yield作用:阻断并返回。
使用yield的生成器函数和普通函数的执行流程不一样。普通函数按顺序执行,一次性执行完,遇到return语句或者最后一行函数语句就返回。而生成器函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

接下来使用yield创建一个简单的函数了解其工作流程。

def gene():
    print('return 1 and stop.')
    yield 1
    print('return 2 and stop.')
    yield(2)
    return 3
>>> g = gene()
>>> g
<generator object gene at 0x0000020A1F3B1E40>
    >>> next(g)
    return 1 and stop.
1
>>> next(g)
return 2 and stop.
2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

发现都没有函数return的返回值,该怎么获取呢?该值在最后的报错中,可以通过StopIteration.value获取。

def gene():
    print('return 1 and stop.')
    yield 1
    print('return 2 and stop.')
    yield(2)
    return 3
g = gene()
while True:
    try:
        x = next(g)
        print(x)
    except StopIteration as e:
        print('return:',e.value)
        break

三、迭代器Iterator

可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator)。它是可迭代对象(Iterable),我们可以遍历其所有值。

我们可以通过isinstance()函数来判断一个对象是不是迭代器或者可迭代对象。
迭代器包含了生成器可作用于next()函数的对象,不包含listtupledictsetstr等;
可迭代对象包含迭代器、listtupledictsetstr等可作用于for循环的对象。

>>> from collections.abc import Iterable,Iterator
>>> isinstance([], Iterable)
True
>>> isinstance([], Iterator)
False

>>> isinstance({
    
    }, Iterable)
True
>>> isinstance({
    
    }, Iterator)
False

>>> isinstance('abc', Iterable)
True
>>> isinstance('abc', Iterator)
False

>>> isinstance((x for x in range(3)), Iterable)
True
>>> isinstance((x for x in range(3)), Iterator)
True

listtupledictsetstr等变成迭代器可以使用iter()函数:

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

可以通过map()生成一个迭代器。

>>> func = lambda x : x * x
>>> iter = map(func, [1, 2, 3, 4])
>>> isinstance(iter, Iterable)
True
>>> isinstance(iter, Iterator)
True
>>> next(iter)
1
>>> next(iter)
4
>>> next(iter)
9

四、小结

1、生成器创建方法之一:把一个列表生成式的[]改成();方法之二是在函数中加入yield关键字;
2、迭代器可以被next()函数调用并不断返回下一个值,包含生成器等;list、tuple、dict、set、str等可迭代对象虽然不是迭代器,但可以使用iter()函数作用于它们,使得变成迭代器。

猜你喜欢

转载自blog.csdn.net/qq_45476428/article/details/127523834
今日推荐