使用生成器完成杨辉三角,fibonacci数列等

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对象。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值