系列文章目录
一、可迭代对象
-
迭代:
迭代是一个重复的过程,每次重复都是基于上一次重复的结果,而每一次“重复”被称为一次迭代。
如:将一个列表的元素一个个取出,每次取值的位置,都是在前一次取值的后面一位。
-
可迭代对象:
能够进行迭代取值的对象,如:列表、元组、字符串、文件、迭代器等,都属于可迭代对象。
二、迭代器
-
迭代器:
-
迭代器是可迭代对象的一种,它能记住每次迭代的位置,等下一次迭代时,会从上次迭代的位置继续。
-
迭代器只能往前不会后退,取完一个值后,只能取下一个值,不能取上一个。
-
-
__iter__
、__next__
和next()
的作用:-
__iter__
方法,可以将可迭代对象转换为迭代器; -
__next__
或next()
方法,可以将迭代器对象的值一个个取出:l = [1, 2, 3, 4, 5] l_iterator=l.__iter__() print(l_iterator.__next__()) # 打印:1 print(next(l_iterator)) # 打印:2
-
-
迭代器与其它可迭代对象的区别:
- 其它可迭代对象可以重复迭代,但只能使用for循环来迭代;
- 迭代器只能迭代一次,但可以通过
next()
方法和for循环两种方法进行迭代。
-
创建迭代器:
任何实现了
__iter__
和__next__
方法的对象,都可以称为迭代器。class MyNumbers: def __iter__(self): self.a = 1 return self def __next__(self): x = self.a self.a += 1 return x myclass = MyNumbers() myiter = iter(myclass) # myiter是一个迭代器 print(next(myiter)) # 打印:1 print(next(myiter)) # 打印:2 print(next(myiter)) # 打印:3 print(next(myiter)) # 打印:4 print(next(myiter)) # 打印:5
三、生成器
-
生成器的概念:
生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),不需要再手动实现两方法。它的关键在于yield关键字,具有yield关键字的函数都是生成器!
生成器总是在每次使用到它的时候,将值返回,可以大大节省内存空间。
-
yield关键字的作用:
类似与return,但与return不同的是:yield不仅会将值返回,还会记住当前生成器的执行状态(函数运行到了哪一条语句、迭代到了哪一个值等),等下次再调用netx时,会从上次结束的地方接着执行。
-
自定义生成器:
-
直接将列表的方括号改为圆括号,就形成了一个生成器:
l = [0, 1, 2, 3, 4, 5, 6] g = (x for x in l) print(g) # 打印:<generator object <genexpr> at 0x00000000008ABE40>
-
在函数中使用yield:
def foo(): yield 1 yield 2 yield 3 f = foo() # 获取生成器对象 print(next(f)) # 打印:1 print(next(f)) # 打印:2 print(next(f)) # 打印:3 print(f) # 打印:<generator object foo at 0x0000000006508510>
四、yield表达式
-
作用:
yield表达式不是什么新鲜玩意儿,它其实就是yield的另一种用处:
使用send()
方法可以向yield关键字发送数据,之后就可以使用一个变量来接收这个数据:def foo(): s = yield # 不返回数据,而是接收send()发送来的数据并保存 print(s) s1 = yield print(s1) g = foo() g.send(None) # 相当于next(g),没有这一步会报错,可以理解为初始化 g.send('数据xxx') # 打印:数据xxx