Python 可迭代对象 迭代器 生成器
可迭代对象
可迭代对象有__iter__() 方法
能够被for循环的都是可迭代对象,
字符串、列表、元组、字典、集合、打开的文件句柄都是可迭代对象
迭代器
可迭代对象执行__iter__或者iter()后得到迭代器,迭代器有一个方法__next__ next()
迭代器的优点:
- 惰性计算,节省内存 惰性计算就是表达式不在绑定变量后立即求值,而是在取用的时候求值
- 不依赖索引
缺点: - 不如索引取值方便
- 一次性,只能往前取,不能后退
生成器
生成器是含有yield的函数,本质是迭代器
下面是用列表的__iter__() 方法生成一个生成器,在循环中使用__next__()方法 依次取值,取完后通过异常处理,捕捉迭代停止异常
yield可以保存函数的状态
for循环的本质
迭代器在用for循环取值的时候,取完后不会报错,但是迭代器用__next__()一直取会报错 StopIteration,
下面把列表用__iter__() 制作成迭代器,在while循环中用try捕捉异常,循环执行__next__()取值,知道异常后终止循环。
i = [1,2,3,4].__iter__()
while True:
try:
x = i.__next__()
print(x)
except StopIteration:
break
也可以是下面的方式
i = [1,2,3,4]
i = iter(i)
while True:
try:
x = next(i)
print(x)
except StopIteration:
break
无限计数 和无限循环
from itertools import count
counter = count(start=1)
print(next(counter))
print(next(counter))
print(next(counter))
from itertools import cycle
color = cycle(['red', 'green', 'yellow'])
print(next(color))
print(next(color))
print(next(color))
print(next(color))
print(next(color))
自己写一个生成器
def g():
print('a generator')
yield 1
ret = g()
print(ret)
上面执行g()的时候就生成一个生成器<generator object g at 0x0000000002B69150>,此时并没有执行函数的中的打印,
这是生成器的一个重要的特点,就是在执行g()的时候,生成一个生成器,只有在迭代它(调用__next__()的时候才执行函数内部的代码),遇到yield就返回yield后面的值并停止。
yield 与return的区别
可以有多个yield,但是return 在函数中只有一个,return返回后,函数就停止了。
yield之后可以保存函数的运行状态
def test_yield():
yield 1
yield 2 # 下次next()后执行
yield 3 # 下次next()后执行
yield的作用
1 把函数变成了生成器,(生成器就是迭代器)
2 为函数封装了__iter__() 和__next__() 方法,把函数的执行结果做成了迭代器
3 遵循迭代器的取值方式obj.next()触发函数的执行,函数的暂停和继续运行的状态由yield保存
生成器表达式
之前学的列表生成式[i for i in range(10) ] 创建数量小的列表的时候是很方便的,但是如果创建很大的列表,会占用很多的内存。
因此生成器表达式出现了,就是把[] 换成了(),就得到了一个生成器对象,可以用next() 一个个的取值,还可以用for循环取值
for i in (i for i in range(10)):
print(i)
(i for i in range(10000000000)) 即便是创建很大的生成器,内存也不会爆
参考:
https://q1mi.github.io/PythonBlog/post/iterator/
https://q1mi.github.io/PythonBlog/post/generator/
http://python.jobbole.com/87805/
http://www.cnblogs.com/demon89/p/7424974.html

浙公网安备 33010602011771号