1.生成杨辉三角
杨辉三角形式如下
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
下面我们使用生成器,来生成一个杨辉三角。
def yanghui_triangles():
n, a = 1, [1]
while n < 7:
yield a
tmp = [1] * (n+1)
# 该轮有n+1个元素,第一个元素与最后一个均为1,给中间n-1个元素赋值
for i in range(1, n):
tmp[i] = a[i-1] + a[i]
a = tmp
n += 1
def print_yanghui():
for curlist in yanghui_triangles():
print(curlist)
代码输出结果:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
我们使用yield关键字,产生一个生成器,每次输出当前行序列。
2.生成fibonacci数列
def fig_generator(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
def get_fib_num():
f = fig_generator(6)
while True:
try:
num = next(f)
print("num is: ", num)
except StopIteration as ex:
print('return value is:', ex.value)
break
get_fib_num()
代码的输出如下:
num is: 1
num is: 1
num is: 2
num is: 3
num is: 5
num is: 8
return value is: None
3.手动实现生成器
class FibGenerator(object):
def __init__(self, n):
self.__n = n
self.__s0 = 0
self.__s1 = 1
self.__count = 0
def __next__(self):
if self.__count < self.__n:
self.__s0, self.__s1 = self.__s1, self.__s0 + self.__s1
self.__count += 1
return self.__s0
else:
raise StopIteration
def __iter__(self):
return self
def gen_fib():
fib = FibGenerator(10)
print(isinstance(fib, Iterable))
for num in fib:
print(num)
gen_fib()
代码输出为:
True
1
1
2
3
5
8
13
21
34
55
任何一个生成器,都会有一个__next__方法,该方法在最后一个元素之后需要抛出StopIteration异常。对于next()函数来说,本质就是调用对象中的__next__()方法。这个方法或者返回迭代的下一项,或者抛出结束迭代的StopIteration异常。
而对象中定义了__iter__()方法,定义该方法以后,就可以使用for循环与in语句来访问了,否则只能使用next()方法进行迭代。同时定义了__next__与__iter__两个方法的对象称为迭代器(Iterator)。
4.小结
1.凡是可作用于for循环的对象都是Iterable类型;
2.for循环的本质就是不停调用next()方法。
3.凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列。
4.list, dict, str等是Iterable类型,但不是Iterator对象。我们可以通过iter()方法获得一个Iterator对象。