使用列表推导在Python中迭代算法生成帕斯卡尔三角形

0 投票
3 回答
2567 浏览
提问于 2025-04-17 04:55

为了练习,我正在尝试用Python的列表推导式来表示帕斯卡三角形,而且是以迭代的方式来实现。我在Python中表示帕斯卡三角形的方式是:

tri = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], ...]

因为我是以迭代的方式来做,所以我需要以某种方式访问之前计算过的三角形的行,而我想要做到这一点是不声明局部变量

到目前为止,我有这个:

tri = [lines.append(
    ([1] + [lines[i][j]+lines[i][j-1] for j in xrange(1, i+1)] + [1]) if i > 0 
        else [1, 1]) 
    or lines[i] for i, lines in enumerate([[[1]]]*height)]

有什么想法吗?

编辑:正如@brc指出的,这其实是一个很糟糕的例子,说明了何时以及如何使用列表推导式。

3 个回答

1

因为我们需要明确的循环方法,所以我会使用一个迭代器。

def bincoeff(num=None):
    from math import factorial
    if num is None:
        it = iter(lambda: True, False) # waiting for Godot
    else:
        it = xrange(num)
    for _ in it:
        yield [factorial(n) // (factorial(k) * factorial(n - k)) for k in range(n+1)]

使用这个生成器,你可以

  • 创建一个列表:

    bc = list(bincoeff(100))
    
  • 获取所有直到某个最大值:

    for bc in bincoeff():
        if len(bc) > 100: break
        print bc
    
  • ...

9

你可以简单地使用二项式系数的定义:

from math import factorial
tri = [[factorial(n) // (factorial(k) * factorial(n - k)) for k in range(n+1)]
  for n in range(height)]
1

根据你给自己设定的那些有点疯狂的限制,我能想到的唯一简化方法就是这里的内容:

[d.setdefault(j, [sum(d[len(d)-1][max(i, 0):i + 2]) for i in range(-1, j)])
 for j, d in enumerate([{0: [1]}] * 5)]

至少这个版本比你之前的短,而且去掉了所有的条件表达式。当然,这个方法还是有点疯狂。

撰写回答