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

posted @ 2017-08-24 19:13  hzxPeter  阅读(108)  评论(0)    收藏  举报