迭代器iterator

  • 迭代简单理解就是重复,但是每次重复产生的结果还要作为下次重复的初始值。
  • 可迭代对象:含有——iter——方法的对象。
  • 可以用for...in..遍历的都是可迭代对象。
  • 字符串 字典 列表 元组等可以被遍历的对象都是可迭代对象。
  • 迭代器:既有iter方法,还有next方法,算是可迭代对象的特例
  • 迭代器是可以记住遍历位置的对象
  • 可迭代对象可以用iter()转换为迭代器
  • 可以使用 isinstance() 判断一个对象是否是 Iterable 对象:
import time
# 3.7 用这句
# from collections import Iterable

# 现在3.10就用这句
from collections.abc import Iterable

a = '12345678'

print('111111111111')
# 下边两句发现字符串是可迭代对象,但是没有next方法说明不是迭代器
print(isinstance(a, Iterable))  # True
# next(a) # TypeError: 'str' object is not an iterator

print('222222222222')
# 可迭代对象可以用for语句遍历
for i in a:
    print(i)

# 将字符串转换为迭代器  两种转换方法
iterator = iter(a)
b = a.__iter__()

print('3333333333333')
print(b)    # <str_iterator object at 0x0000018BA51D1960>
print(b.__next__())
print(next(b))

print(444444444444)
# 前边调用过两次,这里从3开始
for i in b:
    print(i)

print(555555555555)
# 判断迭代器是不是可迭代对象,迭代器可以认为是可迭代对象的特例
print(iterator)     #<str_iterator object at 0x000001CF87127FD0>
print(isinstance(iterator, Iterable))   # True
# print(type(iterator))   # <class 'str_iterator'>

print(666666666666666)
# 迭代器有next方法,所有的都打印了,再使用就会产生异常
print(next(iterator))
time.sleep(0.1)
print(iterator.__next__())
time.sleep(0.1)
print(next(iterator))
time.sleep(0.1)
print(next(iterator))
time.sleep(0.1)
print(next(iterator))

print(77777777777777)
for i in iterator:
    time.sleep(0.1)
    print(i)



生成器generator

  • 生成器可以产生和迭代器差不多功能的一种数据
  • 要创建一个生成器,有很多种方法,第一种方法很简单,只要把一个列表生成式的[]改成()
  • yield关键字
li = [x**2 for x in range(5)]
print(li)

ge = (x**2 for x in range(5))
print(ge)

print(1111111111111111111)
for i in li:
    print(i)

# next(li) # 列表不能用next

print(22222222222222222)
# 生成器可以使用next
print(ge.__next__())

print(33333333333333333333)
# 生成器可以遍历
for i in ge:
    print(i)


#有了yield关键字,我们就有了一种自定义迭代器的实现方式。
# yield可以用于返回值,但不同于return,
# 函数一旦遇到return就结束了,
# 而yield可以保存函数的运行状态挂起函数,用来返回多次值
# 相当于循环里的 break和continue
# 斐波那契数列 1 1 2 3 5 8 13 21
def fib(max):
    n,a,b = 0,0,1
    while n <max:
        yield b
        a,b = b,a+b
        n = n+1

print(44444444444444)
a = fib(6)
print(a)
print(4545454545454545)
print(a.__next__())
print(next(a))
print(555555555555555)
for i in a:
    print(i)