Если вы открыты для итеративного решения, я подготовил следующее.
from itertools import chain
def pascal(n):
pad = (0,)
result = {1: [1]}
for i in range(2, n + 1):
previous = list(chain(pad, result[i - 1], pad))
result[i] = [sum(pair) for pair in zip(previous, previous[1:])]
return result
Демо-версия:
>>> for n in range(1, 6):
...: print(pascal(n))
...:
...:
{1: [1]}
{1: [1], 2: [1, 1]}
{1: [1], 2: [1, 1], 3: [1, 2, 1]}
{1: [1], 2: [1, 1], 3: [1, 2, 1], 4: [1, 3, 3, 1]}
{1: [1], 2: [1, 1], 3: [1, 2, 1], 4: [1, 3, 3, 1], 5: [1, 4, 6, 4, 1]}
С немного большим количеством строк, но также и более эффективным использованием памяти:
from itertools import chain, tee
def pascal(n):
pad = (0,)
result = {1: [1]}
for i in range(2, n + 1):
previous = chain(pad, result[i - 1], pad)
c1, c2 = tee(previous)
next(c2)
result[i] = [sum(pair) for pair in zip(c1, c2)]
return result
Наконец, наличие dict
с последовательными целочисленными ключами не очень полезно, вы можете просто использовать список, в который вы индексируете, начиная с 0
. Окончательное решение:
def pascal(n):
pad = (0,)
result = [[1]]
for i in range(1, n):
previous = chain(pad, result[i - 1], pad)
c1, c2 = tee(previous)
next(c2)
result.append([sum(pair) for pair in zip(c1, c2)])
return result
Демо-версия:
>>> for n in range(1, 6):
...: print(pascal(n))
...:
[[1]]
[[1], [1, 1]]
[[1], [1, 1], [1, 2, 1]]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
edit: улучшена эффективность за счет отсутствия двух кортежей за итерацию, достаточно создать экземпляр pad
один раз.