您的位置:首页 > 编程语言 > Python开发

Python迭代器与生成器

2019-03-17 20:55 169 查看

 

一、迭代器

迭代就是循环的意思,就是对一个集合中的元素进行循环,从而得到每一个元素。

列表、元组、字典等等这些都是可以通过for循环遍历的数据类型都是可迭代对象,但不是迭代器,可以通过iter()函数将他们转换为迭代器。

[code]f1 = range(1,20,2) #产生一个列表
f = iter(f1) #将列表转换为迭代器
print(f) #打印结果为<range_iterator object at 0x00000206C69BAF10>
print(f.__next__()) #通过__next__()方法逐个访问其内部元素

除了使用iter()函数外,还可以自定义可迭代的类:如果在一个中定义__iter__方法,那么这个类的实例就是迭代器,__iter__方法需要返回一个迭代器,所以就返回对象本身即可(即self)。当对象每一次迭代时,就会调用迭代器中的另一个成员方法__next__方法,该方法需要返回当前迭代的结果。

[code]# 斐波那契类(用迭代器实现)
class Fibonacci(object):
def __init__(self):
self.a = 0
self.b = 1
def __next__(self):
#self.a 就是当前要迭代的值
result = self.a
#计算斐波那契数列下一个值,并将a变成原来的b,将b变成下一个值
self.a,self.b = self.b,self.a + self.b
#返回当前迭代的值
return self.a
#该方法必须要返回一个迭代器
def __iter__(self):
return self
fibs = Fibonacci()
# 对斐波那契数列进行迭代
for fib in fibs:
print(fib,end=" ")
#迭代的值不能超过200
if fib > 500:
break

加强版: 

[code]class Factor(object):
def __init__(self):
self.n = 1
self.res = 1
def __next__(self):
self.res = self.n * self.res
self.n += 1
#如果想让迭代停止,需要抛出StopIteration异常
if self.res > 10000:
raise StopIteration
return  self.res
def __iter__(self):
return self

f1 = Factor()
print(list(f1))
f2 = Factor()
for fib in f2:
print(fib,end = " ")

二、生成器

生成器:

  • 只有在调用的时候才会生成相应的数据(无法利用下标读取数据)
  • 只记录当前位置
  • 只有一个__next_()方法
[code]# 列表生成式
print([x*2 for x in range(1,10)])
# 生成器
a = (x*2 for x in range(1,10))
print(a)
# 通过__next__()方法访问每一个数据
print(a.__next__())

除了使用列表生成式产生生成器外,还可以通过使用yield将函数变为一个生成器

[code]def myGenerator():
numList = [1,2,3,4,5,6,7,8]
for num in numList:
# yield会冻结当前函数,并提交当前要产生的值
yield num
# 产生生成器
num = myGenerator()
print(num.__next__())
print(num.__next__())
[code]# 用生成器实现斐波那契函数
def fib(max_num):
n,a,b = 0,0,1
while n < max_num:
# print(b)
yield b
a,b = b,a+b # 相当于t = (b,a+b),a = t[0] b = t[1]
n += 1
return "Done"

f = fib(10)
while True:
try:
x = f.__next__()
print(x)
#当迭代完成后,可以通过捕捉SyopIteration异常来获取生成器函数return 返回值
except StopIteration as e:
print("Gnerator return Value:",e)
break

利用send函数还可以给yield传值进去

[code]def consume(name):
print("%s 准备吃饭了"%name)
while True:
# 通过yield传值进来并赋给fan变量
fan = yield
print("饭【%s】来了,被【%s】吃了"%(fan,name))

def producer(name):
c = consume("A")
c2 = consume("B")
c.__next__()
c2.__next__()
print("老子开始吃包子了")
for i in range(10):
# send函数可以将参数传给yield然后赋值给fan变量
c.send(i)
c2.send(i)

producer("Ben")

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: