python中的迭代器和生成器

生成器(Generator)

下例中generator_tri的名称叫做生成器(Generator),是一种特殊的 Iterator对象,注意生成器一定是迭代器,迭代器不一定是生成器, 生成器获取方式:

a.Generator函数返回

b.生成器表达式

Generator函数返回,以杨辉三角为例:

from collections import Iterator
from collections import Iterable
from typing import Generator

def triangle():
    result = [1]
    while True:
        yield result
        result = [([0] + result)[i]+(result + [0])[i] for i in range(len(result) + 1)]
generator_tri = triangle()
generator_tri.__next__()
print(next(generator_tri))

print("generator_tri is " + ("Iterator" if isinstance(generator_tri, Iterator) else "not Iterator"))
print("generator_tri is " + ("Iterator" if isinstance(generator_tri, Iterable) else "not Iterable"))
print("generator_tri is " + ("Generator" if isinstance(generator_tri, Generator) else "not Generator"))
print("generator_tri's type is ", type(generator_tri))

生成器表达式:

IL = (x for x in range(10))
print("IL's type is ", type(IL))

运行结果为:

[1, 1]
generator_tri is Iterator
generator_tri is Iterator
generator_tri is Generator
generator_tri's type is  <class 'generator'>
IL's type is  <class 'generator'>

Generator函数

上例中triangle()函数叫做Generator函数,即可以返回生成器(Generator)的函数


迭代器(Iterator)

Iterator对象 必须包含__iter__()函数,__next()__函数(接口), 分别供全局函数 iter()(此函数的功能就是返回一个Iterator对象)和next()调用, Iterator中的__iter__()函数只需要返回它自身即可Iterator对象的获取方式有:

a.生成器(生成器的获取方式见上)

b.Iterable对象(容器类等) 通过iter()函数转换


可迭代对象(Iterable)

list,dict, set 等容器类都是可迭代对象(Iterable),即作为iter()函数的参数,调用后,可返回迭代器的对象,Iterable必须包含__iter__()函数,供全局函数iter()调用, 并返回一个迭代器(Iterator)

L = [x for x in range(10)]
L = iter(L)
print("L's type is ", type(L))
print("s is " + ("Iterable" if isinstance(L, Iterable) else "not Iterable"))

运行结果:

L's type is  <class 'list_iterator'>
s is Iterable

for in 结构的本质

迭代器(Iterator)和可迭代对象(Iterable)都可以作为iter()函数的参数,都返回一个迭代器(Iterator)(对于Iterator做参数,返回的就是它自身 ),for ...in ...结构的本质就是调用iter()函数,根据返回的Iterator,然后调用next()函数 进行遍历。

示例1:

for x in [1, 2, 3, 4, 5]:
    pass
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
#it = iter(iter([1, 2, 3,,4, 5]))#多次调用iter()函数时允许的,因为迭代器(Iterator)返回的是自身
# 循环:
#以上代码等价于
while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

示例2:

i = 0
for x in generator_tri:
    i += 1
    if i >5:
        break
    print(x)
#以上代码等价于
it = iter(generator_tri)#it 和generator_tri是一样的
i = 0
while i < 5:
    i += 1
    x = next(it)
    print(x)


自定义迭代器Iterator

我们可以自定义一个类,包含__iter__() __next()函数,根据鸭子类型,冒充迭代器(Iterator),调用isinstance()判断是否是Iterator,返回true
class Fib(object):
    def __init__(self, max_lim):
        self.a, self.b = 0, 1
        if max_lim >= 0:
            self.__max_lim = max_lim
        else:
            self.__max_lim = 0
    def __iter__(self):
        '供iter()调用,返回迭代器'
        return self
    def __next__(self):
        '供next()函数调用'
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.__max_lim:
            raise StopIteration()
        return self.a


f = Fib(1000)
print("f is " + ("Iterator" if isinstance(f, Iterator) else "not Iterator"))
print("f is " + ("Iterable" if isinstance(f, Iterable) else "not Iterable"))
print("f is " + ("Generator" if isinstance(f, Generator) else "not Generator"))
print(type(f))
print(next(f))

运行结果为:

f is Iterator
f is Iterable
f is not Generator
<class '__main__.Fib'>
1


小结

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

参考:

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014317799226173f45ce40636141b6abc8424e12b5fb27000

迭代器生成器Python 用于处理可迭代对象的两种重要机制。 迭代器是一个实现了迭代协议的对象,它通过定义 `__iter__()` 和 `__next__()` 方法来实现。`__iter__()` 方法返回迭代器本身,而 `__next__()` 方法返回下一个元素。当没有更多元素时,`__next__()` 方法会引发 `StopIteration` 异常。可以使用内置的 `iter()` 函数从可迭代对象获取迭代器生成器是一种特殊的迭代器,它使用函数来创建。生成器函数使用 `yield` 语句来产生一个值,并在下次调用时从离开的地方继续执行。与普通函数不同,生成器函数在调用时不会立即执行,而是返回一个生成器对象。可以使用 `next()` 函数或 `for` 循环来迭代生成器对象。 使用生成器可以有效地处理大型数据集或无限序列,因为它们按需生成值,而不需要一次性将所有值存储在内存。 下面是一个迭代器生成器的示例代码: ```python # 迭代器示例 class MyIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.data): raise StopIteration value = self.data[self.index] self.index += 1 return value my_iter = MyIterator([1, 2, 3]) for num in my_iter: print(num) # 生成器示例 def my_generator(data): for num in data: yield num my_gen = my_generator([1, 2, 3]) for num in my_gen: print(num) ``` 输出结果为: ``` 1 2 3 1 2 3 ``` 希望以上内容能对你有所帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值