注意:
1、如果一个函数中包含yield关键字,那么这个函数就会变成生成器函数,而调用一个生成器函数将会返回一个生成器的数据
2、调用生成器函数会创建一个生成器对象,多次调用生成器函数会创建多个相互独立的生成器,示例:
#修改一下脚本 # -*- coding: utf-8 -*- def test(): print('aaa') yield print('bbb') yield print('ccc') yield next(test()) print("1") next(test()) print("2") next(test()) print("3") next(test()) #运行: aaa 1 aaa 2 aaa 3 aaa 可以发现每次都是只到第一个yield就停下了,这就是因为只调用了生成器函数,所以每次都是创建新的生成器,而上一个脚本是把生成器函数赋值了,每次调用的是相同的生成器,很明显上一个脚本的写法才是正确的
注意:生成器函数的调用会直接返回一个生成器对象,而普通函数会直接返回调用结果
四、迭代器
经过上面的学习,可以知道可以直接进行for循环的数据类型有:列表(list),元组(tuple)、字典(dict)、集合(set)、字符串(str)等,这些都是集合数据类型的,还有一个种是生成器(generator),包括了生成器和生成器函数(带yield关键字的函数)
for循环可以作用于上述所说的所有数据类型,而这些数据类型又称为可迭代数据类型(Iterable),利用isinstance()函数可以判断一个数据是否为可迭代的数据类型
>>> from collections.abc import Iterable >>> isinstance([], Iterable) True >>> isinstance({}, Iterable) True >>> isinstance('aaa', Iterable) True >>> isinstance((i for i in range(10)), Iterable) True >>> isinstance(100, Iterable) False #注意:int类型不是可迭代的数据类型
- 我们知道生成器不但可以使用for循环,还可以使用
next()
函数不断调用直到抛出StopIteration
错误,而这种可以被next()
函数调用并不断返回下一个值的数据类型,也叫做迭代器(Iterator)
,同样的使用isinstance()
函数可以判断是否为迭代器:
>>> from collections.abc import Iterator >>> isinstance([], Iterator) False >>> isinstance({}, Iterator) False >>> isinstance('aaa', Iterator) False >>> isinstance((i for i in range(10)), Iterator) True #可以看到只有生成器是迭代器
注意:生成器为Iterable而迭代器为Iterator
- 经过上面的案例,可以看出生成器既是可迭代数据类型,也是迭代器数据类型,但是为什么其他的可迭代数据不是迭代器数据类型呢?如列表、字典、字符串等
这是因为python中的迭代器表示的是一个数据流,这个数据流是可以被next()函数不断调用并返回下一个值,直到没有数据时报StopIteration错误。
这也说明了迭代器的计算是惰性的,只有在需要返回下一个数据时才会进行计算,而列表、字典、字符串这些数据在创建的时候,里面的元素就已经定义好了,在需要返回时并不会计算,而是直接返回。
他们的区别还在于迭代器可以表示一个无限大的数据流,例如所有自然数,因为他的计算模式是惰性的,而像列表、字典、字符串这种的,很明显存储的元素是有限的,所以它们不是迭代器的数据类型
列表、字典、字符串等虽然不是迭代器的数据类型,但是可以通过函数iter()来获取一个迭代器的数据,例如:
>>> from collections.abc import Iterator >>> isinstance(iter([]), Iterator) True >>> isinstance(iter({}), Iterator) True >>> isinstance(iter('aaa'), Iterator) True
最后引入几个知识点:
1、python的for循环本质就是通过不断调用next()函数实现的
2、凡是for循环可以调用的类型都是可迭代数据类型
3、凡是可以使用next()函数不断调用输出结果的数据都是迭代器数据类型
以看出生成器既是可迭代数据类型,也是迭代器数据类型,但是为什么其他的可迭代数据不是迭代器数据类型呢?如列表、字典、字符串等
这是因为python中的迭代器表示的是一个数据流,这个数据流是可以被next()函数不断调用并返回下一个值,直到没有数据时报StopIteration错误。
这也说明了迭代器的计算是惰性的,只有在需要返回下一个数据时才会进行计算,而列表、字典、字符串这些数据在创建的时候,里面的元素就已经定义好了,在需要返回时并不会计算,而是直接返回。
他们的区别还在于迭代器可以表示一个无限大的数据流,例如所有自然数,因为他的计算模式是惰性的,而像列表、字典、字符串这种的,很明显存储的元素是有限的,所以它们不是迭代器的数据类型
列表、字典、字符串等虽然不是迭代器的数据类型,但是可以通过函数iter()来获取一个迭代器的数据,例如:
>>> from collections.abc import Iterator >>> isinstance(iter([]), Iterator) True >>> isinstance(iter({}), Iterator) True >>> isinstance(iter('aaa'), Iterator) True
- 最后引入几个知识点:
1、python的for循环本质就是通过不断调用
next()
函数实现的2、凡是for循环可以调用的类型都是可迭代数据类型
3、凡是可以使用
next()
函数不断调用输出结果的数据都是迭代器数据类型