生成器
只有在调用的时候才会生成相应的数据
只能逐个往后取(不能取前面的,也不能直接跳到后面)
取值只有一个__next()__方法(Python3)next()(Python2)
send()不仅能像next()读下一项,同时还能往yield发送指定内容
两种实现方式
1.生成器表达式,语法看似列表推导式,只是把最外层的中括号改为小括号。
>>> a = (i for i in range(8)) >>> a <generator object <genexpr> at 0x000001D1C9FB8A98> >>> dir(a) ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
2.函数(通过yield关键字)
#coding=utf-8 def natural_number(): '''自然数''' n = 0 while True: yield n n += 1 n = natural_number() print n.next() print n.next() print n.next() print n.next() print n.next() 0 1 2 3 4
#coding=utf-8 def fib(x): # 斐波拉契数列 n, a, b = 0, 0, 1 while n < x: yield b a, b = b, a + b n += 1 f = fib(6) print f.next() print f.next() print f.next() print f.next() print f.next() print f.next() 1 1 2 3 5
通过yield在单线程的情况下实现并发运算的效果
#coding=utf-8 # 生产者消费者模型 def write_code(name): print '注意了!{}要开始写代码了!'.format(name) rc_1 = read_code('华哥', '测试') rc_2 = read_code('我', '解决') rc_1.next() rc_2.next() for i in xrange(1, 7): print '{}写了{}行代码!'.format(name, i) rc_1.send(i) rc_2.send(i) def read_code(name, type): print '{}在旁边帮辉哥{}bug!'.format(name, type) while True: line = yield print '{}已经{}了{}个bug'.format(name, type, line) write_code('辉哥')
注意了!辉哥要开始写代码了!
华哥在旁边帮辉哥测试bug!
我在旁边帮辉哥解决bug!
辉哥写了1行代码!
华哥已经测试了1个bug
我已经解决了1个bug
辉哥写了2行代码!
华哥已经测试了2个bug
我已经解决了2个bug
辉哥写了3行代码!
华哥已经测试了3个bug
我已经解决了3个bug
辉哥写了4行代码!
华哥已经测试了4个bug
我已经解决了4个bug
辉哥写了5行代码!
华哥已经测试了5个bug
我已经解决了5个bug
辉哥写了6行代码!
华哥已经测试了6个bug
我已经解决了6个bug
迭代器
可迭代对象(Iterable):可作用于for循环的对象统称为可迭代对象
迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象成为迭代器
生成器都是可迭代对象,但list, tuple, str不是,可以通过iter()函数转换
instance可以判断某对象是否为可迭代对象或者是否为迭代器
#coding=utf-8 from collections import Iterable, Iterator a = dict() print '变量a是一个可迭代对象:', isinstance(a, Iterable) print '变量a是一个迭代器:', isinstance(a, Iterator) b = (x for x in xrange(6)) print '变量b是一个可迭代对象:', isinstance(b, Iterable) print '变量b是一个迭代器:', isinstance(b, Iterator) 变量a是一个可迭代对象: True 变量a是一个迭代器: False 变量b是一个可迭代对象: True 变量b是一个迭代器: True