确定代码查看:
import math# pascals_tri_formula = [] # don't collect in a global variable.def combination(n, r): # correct calculation of combinations, n choose k return int((math.factorial(n)) / ((math.factorial(r)) * math.factorial(n - r)))def for_test(x, y): # don't see where this is being used... for y in range(x): return combination(x, y)def pascals_triangle(rows): result = [] # need something to collect our results in # count = 0 # avoidable! better to use a for loop, # while count <= rows: # can avoid initializing and incrementing for count in range(rows): # start at 0, up to but not including rows number. # this is really where you went wrong: row = [] # need a row element to collect the row in for element in range(count + 1): # putting this in a list doesn't do anything. # [pascals_tri_formula.append(combination(count, element))] row.append(combination(count, element)) result.append(row) # count += 1 # avoidable return result# now we can print a result:for row in pascals_triangle(3): print(row)
印刷品:
[1][1, 1][1, 2, 1]
帕斯卡三角形的解释:
这是“
n选择k”的公式(即,从n项的有序列表中有多少种不同的方式(不考虑顺序),我们可以选择k项):
from math import factorialdef combination(n, k): """n choose k, returns int""" return int((factorial(n)) / ((factorial(k)) * factorial(n - k)))
一个评论者问这是否与itertools.combinations有关-确实如此。“ n select k”可以通过组合中元素列表的长度来计算:
from itertools import combinationsdef pascals_triangle_cell(n, k): """n choose k, returns int""" result = len(list(combinations(range(n), k))) # our result is equal to that returned by the other combination calculation: assert result == combination(n, k) return result
让我们看看这个演示:
from pprint import pprintptc = pascals_triangle_cell>>> pprint([[ptc(0, 0),], [ptc(1, 0), ptc(1, 1)], [ptc(2, 0), ptc(2, 1), ptc(2, 2)], [ptc(3, 0), ptc(3, 1), ptc(3, 2), ptc(3, 3)], [ptc(4, 0), ptc(4, 1), ptc(4, 2), ptc(4, 3), ptc(4, 4)]],width = 20)[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
我们可以避免使用嵌套列表理解来重复自己:
def pascals_triangle(rows): return [[ptc(row, k) for k in range(row + 1)] for row in range(rows)]>>> pprint(pascals_triangle(15))[[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], [1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1], [1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1], [1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1], [1, 14, 91, 364, 1001, 2002, 3003, 3432, 3003, 2002, 1001, 364, 91, 14, 1]]
递归定义:
我们可以使用三角形所示的关系来递归定义(效率较低,但数学上可能更优雅的定义):
def choose(n, k): # note no dependencies on any of the prior pre if k in (0, n): return 1 return choose(n-1, k-1) + choose(n-1, k)
有趣的是,您可以看到每一行的执行时间逐渐变长,因为每一行必须重新计算上一行中的几乎每个元素两次:
for row in range(40): for k in range(row + 1): # flush is a Python 3 only argument, you can leave it out, # but it lets us see each element print as it finishes calculating print(choose(row, k), end=' ', flush=True) print()11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 11 6 15 20 15 6 11 7 21 35 35 21 7 11 8 28 56 70 56 28 8 11 9 36 84 126 126 84 36 9 11 10 45 120 210 252 210 120 45 10 11 11 55 165 330 462 462 330 165 55 11 11 12 66 220 495 792 924 792 495 220 66 12 11 13 78 286 715 1287 1716 1716 1287 715 286 78 13 11 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 11 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 11 16 120 560 1820 4368 8008 11440 12870 11440 8008 4368 1820 560 120 16 11 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 11 18 153 816 3060 8568 18564 31824 43758 48620 43758 31824 18564 8568 3060 816 ...
厌倦了Ctrl-C退出时,它会变得非常慢非常快…



