迭代器与生成器

迭代器


  • 迭代器可以记住元素的位置
  • 只会往前不能往后
  • 可以用 iter()创建迭代器对象
  • 用 next()打印出来,可以看到第一个 next()的值只会打印第一个
  • 可以用 for 循环遍历出来,for 循环是一个特殊的迭代器
list1 = [1, 2, 3, 4]

# 创建迭代器对象
a = iter(list1)
print(next(a))
print(next(a))
print(next(a))

# 用for循环遍历出来
for i in a:
    print(i)

用 class 创建迭代器


  • __iter__() 方法返回的是一个迭代器对象
  • __next__() 方法会返回下一个迭代器对象
# 创建迭代器
class Test:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        x = self.a
        self.a += 1
        return x
    
test = Test()
test_iter = iter(test)
print('-------------------------')
print(next(test))
# 1
# print(next(test))
# print(next(test))
print(test)
# <__main__.Test object at 0x00000219CD42A0A0>
# print(test_iter)
# <__main__.Test object at 0x00000219CD42A0A0>
print(type(test))
# print(type(test_iter))

image.png

  • 无论打印 test 对象还是打印 test_iter 对象,它们都是 Test()类的实例对象,都会,返回同样的字符串形式

image.png

  • 或者在 print (next (test.__iter__())) 也会正常输出,是因为调用了 Test 类中的 __iter__方法

StopIteration


StopIteration 用于标识迭代完成,防止出现无限循环的情况,在 __next__() 方法中可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代

  • 例子在迭代 20 次后停下迭代
12345678910111213141516171819Traceback (most recent call last):
  File "d:\桌面\python基础\14.迭代器StopIteration.py", line 31, in <module>
    print(next(test_iter), end='')
  File "d:\桌面\python基础\14.迭代器StopIteration.py", line 24, in __next__
    raise StopIteration('超过了')
StopIteration: 超过了

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "d:\桌面\python基础\14.迭代器StopIteration.py", line 32, in <module>
    except StopIteration('超过20 了'):
TypeError: catching classes that do not inherit from BaseException is not allowed

生成器


  • 使用了 yield 函数被称作是生成器
  • 生成器就是一种特殊的迭代器
  • 调用生成器函数返回的是一个迭代器对象
  • 在调用 yield 函数生成,在每次执行到 yield 函数时会暂停保存当前运行的所有信息,并在下一次执行 next()方法时从当前位置执行

案例

# 调用生成器实现斐波那契数列
# 两数之和等于第三个数,用第三个数加下一个数

import sys

def generate(n):
    a,b, counter = 0, 1, 0
    while True:
        if counter>n:
            return
        yield a
        a, b = b, a+b                
        counter += 1

g = generate(20)

while True:
    try:
        print(next(g), end='')
    except StopIteration:
        sys.exit()
posted @ 2023-06-10 16:00  鱼仔_yuzai  阅读(19)  评论(0)    收藏  举报