迭代器
•可以通过 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>>: