生成器与迭代器

生成器

              只有在调用的时候才会生成相应的数据

              只能逐个往后取(不能取前面的,也不能直接跳到后面)

              取值只有一个__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
原文地址:https://www.cnblogs.com/allenzhang-920/p/8922662.html