首页 > 代码库 > 迭代器和生成器

迭代器和生成器


可迭代对象:
可以通过for...in...这类语句迭代读取一条数据供我们使用的对象称之为可迭代对象(Iterable)
一个具备了__iter__方法的对象,就是一个可迭代对象。

怎么判断是否为可迭代对象:
1.能使用for …in … 语句进行迭代的
2.使用 isinstance() 判断一个对象是否是 Iterable 对象, 判断是否是迭代器用 Iterator
In [7]: from collections import Iterable
In [8]: isinstance([], Iterable )
Out[8]: True
返回True就是可迭代对象,false就不是可迭代对象。

迭代器:
有__iter__ ,__next__ 方法的对象,就是迭代器

生成器:
生成器是一种特殊的迭代器
1. 第一种方法很简单,只要把一个列表生成式的 [ ] 改成 ( )
A = (x for x in ragne(10))
2. 第二种方法:
关键字:yield

yield关键字有两点作用:

def gen():
i = 0

while i < 5:
temp = yield i # 暂停时,i值返回给外部的next(G)调用
# temp是恢复时,通过 G.send(‘hello‘)传入进来

print("temp = %s" % temp)

i += 1

? 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
? 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
? 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)


用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
In [39]: g = fib(5)
In [40]: while True:
....: try:
....: x = next(g)
....: print("value:%d"%x)
....: except StopIteration as e:
....: print("生成器返回值:%s"%e.value)
....: break


生成器的唤醒:
1. Next() 只能获取数据
2. Send() send()函数的一个好处是可以在唤醒的同时向断点处传入一个附加数据。

闭包:

1. 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
2. 闭包也具有提高代码可复用性的作用

1. 内部函数修改外部函数中的变量:
2. Python3 使用 nonlocal 关键字

def counter(start=0):
def incr():
nonlocal start
start += 1
return start
return incr
c1 = counter(5)
print(c1())
print(c1())

3. Python2 没有nonlocal 关键字,可以通过定义列表间接修改。

def counter(start=0):
count=[start]
def incr():
count[0] += 1
return count[0]
return incr
c1 = counter(5)
print(c1())#6
print(c1())#7

 

 

 

技术分享

迭代器和生成器