python generator输出_Python高级特性——生成器(generator)

通过上节的学习,我们知道使用列表生成式,可以直接创建一个列表。但是,有些时候,受到内存的限制等实际情况,列表生成式无法满足。比如,一个长度为1000万的列表,普通内存根本就不够,又或者实际处理的过程中,我们只需要访问前面几个元素,那后面的的绝大部分的空间都浪费了。

思路:如果能做到一开始并不是创建完整的list,而是通过定义一种规则的方式,在循环的过程中不断的推算后续的元素,达到使用到哪个元素才生成哪个元素的效果?在Python中,这种机制称为生成器:generator。

创建generator,方法一:

>>> m = (x for x in range(10))>>>m at 0x0376BF00>

观察可知,和列表生成式相比,区别仅仅在于将最外层的[]换成()。请注意,m并不是一个list,而是一个generator。如何打印generator中的每一个元素呢?笨重方法(该方法基本用不到):

>>>next(m)

0>>>next(m)1

>>> l = ['hah','hehe']

>>> next(m)

2

中间有个小插曲,随便做了一个操作,紧接着我们又调用next函数,发现结果还是按照算法计算出下一个值。(当生成器没有更多的元素的时候,会抛出StopIteration错误)

方便的取元素方法:因为generator是可迭代对象(从StopIteration错误类型,我们也可以猜测出来),我们可以使用for循环实现取数:

>>> n = (a+b for a in 'abc' for b in 'xyz')>>> for i inn:

...print(i)

...

ax

ay

az

bx

by

bz

cx

cy

cz

方法二:

如果上述中的推算算法比较复杂,使用方法一无法实现的时候,可以使用函数来实现。比如著名的斐波拉契数列(1,1,2,3,5,8,13,21……除了第一个和第二个数外,任意一个数都是由其前两个数相加的和)。斐波拉契数列使用列表生成式写不出来,可以使用函数把它打印出来:

>>> deffib(max):

... n,a,b= 0,0,1...while n

...print(b)

... a,b= b,a+b#相当于将一个tuple(b,a+b)赋值给a,b

... n = n + 1...return...>>> fib (6)1

1

2

3

5

8

其实,上述fib()和generator非常相近了。只需要把print(b)变成yield b 就可以了:

>>> deffib(max):

... n,a,b= 0,0,1...while n

...yieldb

... a,b= b,a+b

... n= n+ 1...return...>>> fib(6)

这就是定义generator的第二种方法。如果一个函数中包含yield关键字,那么这个函数就不再是普通函数,而是一个generator。两者的执行流程可以这么区别:普通函数是顺序执行,遇到return或者最后一行代码函数就会返回。而generator,在每次调用next()的时候执行,遇到yield语句返回。再次执行的时候,从上次返回的yield语句处继续执行。

使用for循环来迭代:

>>> m = fib(5)>>> for i inm :

...print(i)

...1

1

2

3

5

那么如何获取一个generator中的return的值呢?这时必须捕获StopIteration错误,返回值就包含在StopIteration的value中:

>>> deffib(max):

... n ,a,b= 0,0,1...while n

...yieldb

... a,b= b,a+b

... n= n+1...return 'Over'...>>> m = fib(6)>>> whileTrue:

...try:

... x=next(m)

...print(x)

...exceptStopIteration as e:

...print(e.value)

...break...1

1

2

3

5

8Over

练习:

杨辉三角:

1      n=0

/ \

1 1     n=1

/ \ / \

1 2 1    n=2

/ \ / \ / \

1 3 3 1   n=3

/ \ / \ / \ / \

1 4 6 4 1  n=4

/ \ / \ / \ / \ / \

1 5 10 10 5 1 n=5

杨辉三角,把二项式系数图形化,把组合数内在的一些代数性质直观的从图形中表现出来,是一种离散型的数与形的优美结合。

有如下规律:

1,每行端点和结尾的数为1;

2、每行数左右对称,由1开始逐渐变大;

3、第n行有n项;

4、第n行数字之和为2的n-1次方;

5、第n行的m个数可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数;

6、第n行的第m个数和n-m+1个数相等,为组合数性质之一;

7、每个数字等于上一行的左右两个数字之和;(利用此性质可写出整个杨辉三角)

8、(a+b)

n

的展开式中的各项系数依次对应杨辉三角的第(n+1)行中的每一项

如果把杨辉三角的每一行看做一个list,试写一个generator,不断输出下一行的list:

>>> deftriangle():

... l=[1]

...whileTrue:

...yieldl

... l.append(0)

... l= [l[i-1]+l[i] for i inrange(len(l))]

...

验证一下:

>>> x =triangle()>>>next(x)

[1]>>>next(x)

[1, 1]>>>next(x)

[1, 2, 1]>>>next(x)

[1, 3, 3, 1]>>>next(x)

[1, 4, 6, 4, 1]>>>next(x)

[1, 5, 10, 10, 5, 1]>>>next(x)

[1, 6, 15, 20, 15, 6, 1]>>>next(x)

[1, 7, 21, 35, 35, 21, 7, 1]>>>next(x)

[1, 8, 28, 56, 70, 56, 28, 8, 1]>>>next(x)

[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]>>>next(x)

[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]>>>next(x)

[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]>>>next(x)

[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]

收工!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值