Python 迭代器与生成器

迭代器

迭代器(Iterator)是一个可以记住遍历的位置的对象,该对象包含值的可计数数字,在Python当中:迭代器是实现迭代器协议的对象,它包含方法__iter__() __next__()

__iter__()方法

  • 作用:返回迭代器对象本身

__next__()方法

  • 作用:返回迭代器的下一个元素,如果没有元素了则就会触发StopIteration异常

可迭代对象

如果一个对象/类中,有__iter__()方法并且返回一个迭代器对象,则我们称以这个对象/类创建的对象为可迭代对象。

列表、元组、字典、集合都可以是可迭代的对象。它们都是可迭代的容器,可以从中获取到迭代器

 可以通过dir函数可以列出对象方法

My_list = [1, 2, 3, 4, 5]
a = dir(My_list)
print(a)

实例

My_list = [1, 2, 3, 4, 5]
it = iter(My_list)  # 创建迭代器的对象
print(next(it))  # 输出迭代器的下一个对象
print(next(it))

遍历可迭代对象

我们可以使用for循环来遍历可迭代的对象

my_count = ("one", "tow", "three")

for i in my_count:
  print(i)

创建迭代器

要把对象或者类创建成为迭代器,必须为对象实现__iter__() 方法 和  __next__() 方法

在面向对象编程中类都有一个构造函数,Python的构造函数为__init__(),它会在对象进行初始化的时候执行。

__iter__()方法返回一个特殊的迭代器对象,这个迭代器对象实现了__next__()方法,可以执行操作,但必须返回迭代器对象本身

__next__()方法会返回下一个迭代器对象

实例

class AddOneIterator:
    def __init__(self, start=0):
        self.current = start  # 初始化起始值

    def __iter__(self):
        return self

    def __next__(self):
        self.current += 1
        return self.current
# 创建一个加1的迭代器,从0开始
iterator = AddOneIterator()

# 使用迭代器获取前几个加1后的值
print(next(iterator))  # 输出:1
print(next(iterator))  # 输出:2
print(next(iterator))  # 输出:3
print(next(iterator))  # 输出:4

StopIteration

当我们执行上面代码的时候,可以发现如果有足够的next,或者我们在for循环里面使用,则上面的实例将会一直执行下去。

所以为了防止迭代永远进行,我们可以使用 StopIteration 语句

实例:在next()方法中,我们可以添加一个终止的条件来引发错误

class AddOneIterator:
    def __init__(self, start=0):
        self.current = start  # 初始化起始值

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 10:  # 添加一个if语句
            x = self.current
            self.current += 1
            return x
        else:  # 当大于10的时候终止程序
            raise StopIteration

# 创建一个加1的迭代器,从0开始
iterator = AddOneIterator()

for i in iterator:
    print(i)
输出结果: 1 2 3 4 5 6 7 8 9 10

使用迭代器的好处

  • 节省内存:迭代器允许按需要来生成数据,而不是一次性的将所有数据都加载到内存当中,这对于处理大型数据集非常有效
  • 延迟计算:可以在需要的时候按照需要计算下一个元素,而不是提前计算所有的元素

生成器

生成器是一种特殊的迭代器,它用于创建迭代器

生成器允许你逐个产生值,而不是一次性创建并存储所有值

生成器通过在函数中使用 yield 语句来实现。yield是一个关键字,用于定义生成器函数每次调用生成器函数时,它都会返回一个生成器对象,这个对象可以记住函数执行的位置

当在生成器函数中使用 yield 语句时,函数的执行将会暂停,并将 yield 后面的表达式作为当前迭代的值返回。

然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。这样,生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果

实例

def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
for value in gen:
    print(value)
输出结果:1 2 3

实例

def count():
    for i in range(1, 6):  # range的结束索引是不包含的,所以使用6
        yield i

# 使用生成器
c = count()

for number in c:
    print(number)
输出结果:1 2 3 4 5

下面实例为使用yield实现斐波那契数列

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()
输出结果:0 1 1 2 3 5 8 13 21 34 55

使用生成器的好处

  • 节省内存:因为生成器不需要一次性存储所有值
  • 延迟计算:只有在需要时才计算下一个值

迭代器与生成器的区别

  • 内存使用:生成器通常比迭代器更节省内存,因为它们是按需生成值的。
  • 可迭代性:所有生成器都是迭代器,但不是所有迭代器都是生成器。例如,列表是一个迭代器,但不是生成器。
  • 一次性:迭代器可以多次遍历,而生成器在遍历完成后就不能再次使用了,除非你重新创建它。

生成器提供了一种优雅的方式来处理数据流,特别是当数据集很大或者数据是按需生成的时候。而迭代器则提供了一种通用的方式来遍历任何可迭代对象。

  • 38
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值