datetime:2019/5/16 15:32
author:nzb
迭代器和生成器
和迭代器相关的魔术方法(
__iter__
和__next__
)两种创建生成器的方式(生成器表达式和
yield
关键字)
def fib(num):
"""生成器"""
a, b = 0, 1
for _ in range(num):
a, b = b, a + b
yield a
class Fib(object):
"""迭代器"""
def __init__(self, num):
self.num = num
self.a, self.b = 0, 1
self.idx = 0
def __iter__(self):
return self
def __next__(self):
if self.idx < self.num:
self.a, self.b = self.b, self.a + self.b
self.idx += 1
return self.a
raise StopIteration()
生成器,迭代器的区别?
迭代器:遵循迭代协议的对象。用户可以使用 iter() 以从任何序列得到迭代器(如 list, tuple,dictionary, set 等)。 另一个方法则是创建一个另一种形式的迭代器 —— generator 。要获取下一个元素,则使用成员函数 next()(Python 2) 或函数 next() function (Python 3) 。当没有元素时,则引发 StopIteration 此例外。若要实现自己的迭代器, 则只要实现 next() (Python 2)或 next ()(Python 3)
生成器(Generator):只是在需要返回数据的时候使用yield语句。每次 next() 被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值) 区别: 生成器能做到迭代器能做的所有事,而且因为自动创建 iter() 和 next() 方法,生成器显得特别简洁,而且生成器也是高效的, 使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常。
列表推导式、字典推导式以及生成器
import random
l = [i for i in range(10)]
d = {k: random.randint(4, 9) for k in ['a', 'c', 'd']}
g = (i for i in range(10))
print("列表推导式:{},类型:{}".format(l, type(l)))
print("字典推导式:{},类型:{}".format(d, type(d)))
print("生成器:{},类型:{}".format(g, type(g)))
# 结果
# 列表推导式:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],类型:<class 'list'>
# 字典推导式:{'a': 5, 'c': 6, 'd': 9},类型:<class 'dict'>
# 生成器:<generator object <genexpr> at 0x0000023498EF9390>,类型:<class 'generator'>