【Jupyter notebook 模式 】
总结
Iterable :凡是可以作用于for循环的对象都是Iterable(可迭代的)。Iterator :凡是可以作用于next()函数额对象都是Iterator(迭代器)对象。list、tuple、dict、str、set等都是Iterable(可迭代的) ,因为可以使用for循环遍历,但是它们不是Iterator(迭代器) ,因为不能使用next()函数。 生成器是一种迭代器。 带有yield的函数不再是一个普通的函数,而是一个生成器generator,可用于迭代。 生成器有两个方法:send()和next() ,区别就在于send可传递参数给yield表达式,传递的参数会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。 通俗理解,yield会将生成器函数挂起,保存相关的状态信息,并返回一个值给调用者;next()会重新唤醒生成器函数,并从上一次挂起的位置继续执行。
1、生成器
定义: 在python中,一边做循环,一边计算的机制称为生成器(generator)好处: 使用生成器可以【节约内存】,python在使用生成器时对延迟操作提供了支持。所谓的延迟是指,在需要的时候才会产生结果,而不是立即产生结果存储在内存之中。创建生成器有两种方式:一种是使用类似于列表生成式的方式,只不过把方括号换为圆括号;另外一种是使用生成器函数,在函数定义的时候引入yield语句。
1.1、列表生成式
'''有一个列表,需要将每个元素值加上10'''
alist = [ 0 , 1 , 2 , 3 , 4 , 5 ]
new_list = [ i+ 10 for i in alist]
new_list
[10, 11, 12, 13, 14, 15]
'''使用列表生成式创建一个列表'''
alist = [ x** 2 for x in range ( 5 ) ]
alist
[0, 1, 4, 9, 16]
1.2、生成器表达式创建生成器
gen = ( x** 2 for x in range ( 5 ) )
gen
<generator object <genexpr> at 0x059F7B10>
next ( gen)
0
next ( gen)
1
for x in gen:
print ( x)
4
9
16
当没有元素时就会抛出StopIteration的错误。
next ( gen)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-12-6e72e47198db> in <module>()
----> 1 next(gen)
StopIteration:
1.3、生成器函数创建生成器
在有些时候生成器表达式无法实现一些复杂的功能,此时可以使用 生成器函数。 下面使用**【斐波那契数列】**来解释:
'''普通函数'''
def fib ( max ) :
n, a, b = 0 , 0 , 1
while n< max :
a, b = b, a+ b
print ( a, end= ' ' )
n += 1
return "done"
a = fib( 5 )
1 1 2 3 5
fib( 5 )
1 1 2 3 5
'done'
'''使用生成器'''
def fib ( max ) :
n, a, b = 0 , 0 , 1
while n < max :
a, b = b, a+ b
yield a
n += 1
return 'done'
a = fib( 10 )
a
<generator object fib at 0x00AEEE10>
a. __next__( )
1
for i in a:
print ( i, end= ' ' )
1 2 3 5 8 13 21 34 55
但是上面的程序还有一点小问题:“done”哪去了?怎么打印出来? 我们可以使用异常捕获机制:
Fib = fib( 10 )
while True :
try :
x = next ( Fib)
print ( x, end= ' ' )
except StopIteration as e:
print ( "\n生成器的返回值: " , e. value)
break
1 1 2 3 5 8 13 21 34 55
生成器的返回值: done
2、迭代器
2.1、可迭代对象(Iterable)
可迭代对象主要有两种:1、集合数据类型(list、tuple、dict、set、str等);2、生成器对象
2.2、如何判读是否为Iterable?
可以使用collections中的Iterable模块
from collections import Iterable
List = [ 1 , 2 , 3 ]
Tuple = ( 1 , 2 , 3 )
Str = "123"
Dict = { 0 : 1 , 1 : 10 , 2 : 100 }
Set = set ( [ 1 , 2 , 3 ] )
objs = [ List, Tuple, Str, Dict, Set]
for obj in objs:
print ( "{} is Iterable:{} " . format ( obj, isinstance ( obj, Iterable) ) )
[1, 2, 3] is Iterable:True
(1, 2, 3) is Iterable:True
123 is Iterable:True
{0: 1, 1: 10, 2: 100} is Iterable:True
{1, 2, 3} is Iterable:True
2.3、迭代器(Iterator)
可以使用next()调用并不断返回下一个值得对象称为迭代器。生成器是迭代器的子类。注意集合类型的数据不是迭代器
from collections import Iterator
for obj in objs:
print ( "{} is Iterable:{} " . format ( obj, isinstance ( obj, Iterator) ) )
[1, 2, 3] is Iterable:False
(1, 2, 3) is Iterable:False
123 is Iterable:False
{0: 1, 1: 10, 2: 100} is Iterable:False
{1, 2, 3} is Iterable:False
可以使用iter()函数将上述的集合数据转换为迭代器:
for obj in objs:
print ( "{} is Iterable:{} " . format ( obj, isinstance ( iter ( obj) , Iterator) ) )
[1, 2, 3] is Iterable:True
(1, 2, 3) is Iterable:True
123 is Iterable:True
{0: 1, 1: 10, 2: 100} is Iterable:True
{1, 2, 3} is Iterable:True