一 可迭代对象 Iterable
它包含一个__iter__()
或__getitem__()
方法,一般来说,只要提供了__iter__()
方法都是iterable(字符串str没有__iter__()
,但实现了 __getitem__()
方法 )
二 迭代器对象 Iterator
Python3.x 的特色,与Python2.x相比很多函数的返回值类型改成了Iterator.
迭代器对象 要实现两个方法 __iter__()
和 __next__()
迭代器对象,一定是可迭代对象,因为它实现了__iter__()
方法)
迭代器对象 的本职工作是来做 next 的,为什么还要实现 __iter__()
,返回它自己呢?
一个象容器一样的对象,如果想要可以迭代,就需要实现 __iter__()
这个方法。用这个方法,来返回一个迭代器对象,再调用__next__()
方法,这样的话,就可以被for in这样的语句来处理,象处理序列一样来处理。
x = [1, 2, 3]
for e in x:
...
三 生成器对象 gentator
生成器其实就是一种特殊的迭代器,所以迭代器有的生成器也有.
从某种意义上来说可以节约内存.
生成器的产生有两种方式
1 生成器函数
生成器函数使用yield()函数生成.它可以延迟创建值.(使函数可以暂停或者挂起,并可以从暂停处继续运行或重新开始)
>>> def myfun():
... print('this code will be run')
... yield 1
... yield 2
... yield 3
...
>>> a = myfun()
>>> next(a)
this code will be run
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
自定义函数myfun()中有关键字yield
说明它一定是一个生成器函数,即返回的是一个生成器对象. 而且这个函数执行到 yield 1
的时候就已经暂停了. yield
关键字可以理解为return
但不会终止函数的调用,只是会暂停.
用next()函数可以依次得到生成器的值.直到抛出异常.
生成器当然也可以用for 循环来遍历:
>>> for i in myfun():
... print(i)
...
this code will be run
1
2
3
又例如 面试 问到过的斐波拉契数列:
打印出小于100的数.
def fibo():
a = 0
b = 1
while True:
a, b = b, a+b
yield a
for i in fibo():
if i < 100:
print(i,end=' ')
else:
break
2生成器表达式。
生成器表达式与推导式类似。
在另一篇博客介绍了列表推导式和字典推导式,这里再继续介绍生成器推导式.
x = (i for i in range(5))
print(x)
for a in x:
print(a,end=' ')
#输出
<generator object <genexpr> at 0x10f27b048>
0 1 2 3 4
用小括号()括起来.
元组(tuple)是不可变的,所以没有元组推导式,所以小括号就只单纯的表示函数推导式,也就是生成器推导式,
同理,字符串(str)也是没有推导式的.
列表推导式用中括号[];集合和字典用大括号{};