4、杨辉三角(帕斯卡三角)_python版本

*说明:杨辉三角形,又称贾宪三角形,帕斯卡三角形,是二项式系数在三角形中的一种几何排列。

4、杨辉三角(帕斯卡三角)_python版本_第1张图片


实现方法生成器(generate),详见:廖雪峰_python生成器。

记一下生成器的关键点

1、

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量有限。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

将列表元素按照某种算法推算出来,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。


生成器的概念,如下图所示,生成器g就是用来生成x的平方的东西,结果存在显示的内存地址里。

但是由于你还没说你到底要谁的平方,所以只能看到个地址不能看到答案。

L则不同,它是把所有答案穷举列在内存里了,你需要哪个就从里面找出来即可,比较耗费资源。而g则还没生成,需要哪个我现制造一个出来放在一个内存空间显示,节省了资源。

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
 at 0x1022ef630>

创建列表生成器的区别仅在于最外层的[]()L是一个list,而g是一个generator。

2、

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。

(理解生成器的执行很关键,多多思考,动手试一下)

生成器和函数的执行流程是不一样的。函数是顺序执行,遇到return语句或最后一行函数语句就返回。而生成器在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处执行。

如果需要生成器返回(下一个)值,需要调用.next()函数。其实当系统判断def是生成器时,就会自动支持.next()函数。

上一个例子看一下(例子转自博主,请见:yield理解)


def fib(max):
    a, b = 1, 1
    while a < max:
        yield a
        a, b = b, a+b
 
for n in fib(15):
    print n
 
m = fib(13)
print m
print m.next()
print m.next()
print m.next()

fib()函数因为含有yield,被系统默认为是一个生成器。

for语句调用了fib(15)。当max=15时,进入fib()生成器,执行到yield a, 返回a值以及整个生成器暂停的状态,将a值赋给n, 打印出来;因为是for语句循环,所以又回到fib(15)语句,由于是生成器,因此从上次截断的位置开始执行,b值赋给a, a+b值赋给b,又因为是while语句,则继续while循环,yield a值,循环暂停跳出返回a值及生成器状态,把a值赋给n, 打印n。如此往复,一直循环到15结束。

m被赋了fib(13)这个生成器,每一次执行m.next()函数就会打印下一个值。

运行结果如下:

4、杨辉三角(帕斯卡三角)_python版本_第2张图片
 



有了这些基础就可以考虑实现杨辉三角了,杨辉三角有几个特点:

1、每个数都等于它上方两数之和;

2、每行数字开头结尾都是1,左右对称;

3、数形的实质就是二项式定理,第n行的m个数可表示为 C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数;第n行的数字有n项;第n行数字和为2n-1。(忘记二项式可以移步百科--->二项式定理)。


思路:

我们把每一层看作一个list, 通过一个for循环,通过迭代,每次生成一个list,而生成器就在每一行生成list中起作用。

我们先定义一个函数yanghui_trigangle,作用是生成每一行的list,再通过for循环调用即可得到结果。

方法一:

 

以上为range函数容易混淆的地方。 

#!/user/bin/env.python
# _*_ coding:utf-8 _*_
# _author:poiuyds

# 方法1
def yanghui_triangle():
    L = [1]
    while True:
        yield L
        # list(range(a,a))的输出为空
        L = [1] + [L[i-1] + L[i] for i in range(1,len(L))] + [1]


#if __name__ == ' __main__':
n = 0
for i in yanghui_triangle():
    print(i)
    n += 1
    if n > 10:
        break

输出如下:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]

方法二:

# 方法2
def yh_triangle():
    L = [1]
    while True:
        yield L
        L.append(0)
        # i所生成的每一项就是列表的一项
        L = [L[i-1] + L[i] for i in range(len(L))]

n = 0
for i in yh_triangle():
    print(i)
    n += 1
    if n > 10:
        break

输出如下:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]

 

你可能感兴趣的:(python)