Python迭代器及生成器

迭代器


•可以通过 for 循环来遍历这个 list 或 tuple,这种遍历我们称为迭代(Iteration)
•只要是可迭代对象,无论有无下标,都可以迭代,比如 dict就可以迭代
•通过 collections 模块的 Iterable 类型,为True则可迭代

for循环:

 li=[1,2,3]
 for i in li:
     print i,
 结果:
 1 2 3

collections 模块:

 from collections import Iterable
 print isinstance("dream", Iterable)
 print isinstance([1,2,3], Iterable)
 结果:
 True
 True

iter( )转换li为迭代对象:

 li = range(10)
 it = iter(li)
 it2 = iter(it)
 print it, it2
 print it is it2

 it = li.__iter__()                             ###两者效果一样
 print it.next()
 print it.next()
 结果:
 <listiterator object at 0x7fd41e9a9a10> <listiterator object at 0x7fd41e9a9a10>
 True

 0
 1

程序迭代的写法:

 li = range(3)
 it = li.__iter__()                              ###也可以it = li.ter(li)
 while True:
     try:
         print it.next()
     except StopIteration:
         break
 结果:
 0
 1
 2

列表生成式


for循环:

 li = []
 for i in range(1,5):
     li.append(i*i)
 print li
 结果:
 [1, 4, 9, 16]

列表生成式:

 print [i*i for i in range(1, 5) if i % 2 == 0]
 结果:
 [4, 16]

但是我们发现当我们range的数字较大时,会运行慢,甚至死机。因为是先生成一个列表完成后在进行for循环,但是我们用xrange就可以解决,其是生成一个运行一次,因此不会造成死机的情况,因此不论生成多长的数据都不会卡顿,其实这就相当于生成器。

 for i in xrange(100000000000)
 print i

生成器


为什么需要生成器?

•通过列表生成式,我们可以直接创建一个列表,受到内存限制,列表容量肯定是有限的
•创建一个包含 100 万个元素的列表,占用很大的存储空间

生成器是什么?

在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。在 Python 中,这种一边循环一边计算的机制,称为生成器(Generator)

创建生成器

•把一个列表生成式的 [ ] 改成 ( )
•使用g.next( )方法依次读取元素(麻烦)
•使用 for 循环(推荐)

g.next( ):

 g = (i for i in range(3))
 print g.next()
 print g.next()
 结果:
 0
 1

for循环:

 g = (i for i in range(3))
 for j in g:
     print j
 结果:
 0
 1
 2

实现生成式功能

fib 函数定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,逻辑非常类似 generator。要把 fib 函数变成 generator,只需要把print b 改为 yield b 就可以

函数实现:

 def Fib(max):
     n, a, b = 0, 0, 1
     while n < max:
         print b
         a, b = b, a + b
         n += 1
 Fib(3)
 结果:
 1
 1
 2
 def Fib(max):
     n, a, b = 0, 0, 1
     while n < max:
         yield b                                       ###运行到这里的时候将会退出当前函数接着运行,当再次用到此函数时在接着此处运行
         a, b = b, a + b
         n += 1

 g = Fib(3)
 print g
 for i in g:
     print i
 结果:
 <generator object Fib at 0x7f74446b1d20>
 1
 1
 2

python中yield关键字:

(1)函数中如果有yield,那么调用这个函数的返回值为生成器
(2)当生成器g调用next方法,执行函数,直到遇到yield就停止
(3)再执行next,从上次停止的地方继续执行
(4)函数中遇到return直接退出,不继续执行后面的代码

生成器——无缓冲区的生产者消费者模型

 def consumer(name):
     print "%s 准备买辣条..." %(name)
     while 1:
         kind = yield
         print "客户[%s]购买了[%s]口味的辣条!!!" %(name,kind)
 c1 =consumer("dream")
 c1.next()                                              ###遇到yield停止          
 c1.send("特辣")                                         ###向生成器发送数据
 结果:
 dream 准备买辣条...
 客户[dream]购买了[特辣]口味的辣条!!!

生成器——有缓冲区的生产者消费者模型

 import random
 import time
 cache = []
 def consumer(name):
     print "%s 准备买辣条..." % (name)
     while 1:
         kind = yield
         cache.remove(kind)
         print "客户[%s]购买了[%s]口味的辣条!!!" % (name, kind)
 def producer(name):
     print "厨师[%s]准备制作辣条......" % (name)
     for kind in ["特辣", "微辣"]:
         time.sleep(random.random())
         print "[%s]制作了[%s]口味的辣条,卖给客户..." % (name, kind)
         cache.append(kind)
 producer("Python")
 c1 = consumer("Dream")
 c1.next()
 c1.send("微辣")
 print "本店现有的辣条口味:",
 for i in cache:
     print i, 

生成器throw方法

  def gen():
     while 1:
         try:
             yield 'a'
             yield 'b'
         except TypeError:
             print "Type Error"
         except ValueError:
             print "Value Error"
 g = gen()
 print g.next()
 g.throw(ValueError)
 print g.next()
 结果:
 a
 Value Error
 b

简易机器人:

  def chat_robot():
     res = ''
     while 1:
         receive = yield res
         if 'hi' in receive:
             res = "你好"
         elif 'name' in receive or "姓名" in receive:
             res = "我是机器人小冰..."
         elif 'age' in receive or "年龄" in receive:
             res = '年龄保密......'
         else:
             res = "我不太清除你在说什么..."

 Chat = chat_robot()
 next(Chat)
 while 1:
     send_data = raw_input("Dream>>: ")
     if send_data == 'q' or send_data == "quit":
         print "机器人不和你玩了....."
         break
     response = Chat.send(send_data)
     print "Robot>>: %s" %(response)

 Chat.close
 结果:
 Dream>>: hi
 Robot>>: 你好
 Dream>>: 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wielun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值