如何最简单、通俗地理解Python的迭代器?
我们知道迭代器(iterator)可以用for循环去取数,这和列表取数有什么区别呢?
想理解Python迭起器的差异,有个很简单的例子
打个比方,你去玩街头投篮机,可以投5个球,这里有两种方式:
一种是给你5个球,挨个去投,每个球投完都会留在机器里,而且你可以任选投投球顺序
另一种方式是只给你一个球,投完球会自动滚出来,投完5次后就结束
这两种方式都能让你投完5个球
第一种方式类似列表
列表里的元素是实实在在存在于内存的,就像第一种投篮方式的5个球,摆在那让你投
第二种方式类似迭代器
迭代器里的元素其实是数据流,只有当你使用next()调用它的时候,它才会出来。
这里和第二种投篮方式方式思路接近,只有你发生了投篮行为next(),才会开始下一次投篮。
说到这里,可能你开始有些懂了,但还比较抽象,下面我们看下具体的代码。
# 用列表装5个篮球
this_is_basketball = [1,2,3,4,5]
# 投球
for player in this_is_basketball:
print('投球:',player)
# 用迭代器装5个篮球
this_is_basketball = (x for x in range(1,6))
# 投球
for player in this_is_basketball:
print('投球:',player)
可以看出来迭代器并不真正的把所有篮球都放出来,而是存储了生成元素的逻辑,你每次取的时候,篮球就会挨个被取出来。而列表是把篮球都装进来,for循环挨个投。
用迭代器的好处是你可以投1万次、10万次甚至无数次球,而列表能装的容量总是局限的。
所以说迭代器是一个惰性的数据流。
可迭代对象(Iterable)和迭代器(Iterator)的区别
前面我们说的列表、迭代器都是可迭代对象,就是能够被循环取数的对象
from collections.abc import Iterable
isinstance([], Iterable)
# 返回 True,说明列表是可迭代对象
元组、字典、字符串等也都是可迭代对象。
注意,可迭代对象不可以用next()函数挨个去访问元素
但是迭代器是可以用next()函数挨个去访问元素
可迭代对象可以通过iter函数变成迭代器
from collections.abc import Iterator
isinstance([], Iterator)
# 返回False,说明列表不是迭代器
isinstance(iter([]), Iterator)
# 返回 True,iter函数可以让列表变成迭代器
生成器(generator)和迭代器(Iterator)的区别
你可能看过下面的代码,生成器推导式用于生成序列
this_is_basketball = (x for x in range(1,6))
或者使用yield来生成序列
def generator_(m):
n=0
for i in range(m):
if n < m:
n += 1
yield n
else:
break
这里都是生成器,使用逻辑来表示序列,而很少占用内存
生成器都是特殊的迭代器,可以使用next来取值