Pascal's Triangle in Python: Two Approaches With Sample Output
Print Pascal's triangle in Python using two approaches: row-based dynamic computation and math.comb. Both approaches verified for n=5 rows with sample output.
Pascal’s triangle appears in two different places in a campus placement test: the aptitude section (combinations and probability) and the coding round where you generate it in Python.
What Pascal’s triangle is
Pascal’s triangle is a triangular array where each element is the sum of the two elements directly above it. The boundary elements (the leftmost and rightmost in every row) are always 1.
For five rows (indexed 0 through 4), it looks like this:
Row 0: 1
Row 1: 1 1
Row 2: 1 2 1
Row 3: 1 3 3 1
Row 4: 1 4 6 4 1
Two structural facts that every question about Pascal’s triangle relies on:
- The element at row
i, columnj(both zero-indexed) equals the binomial coefficient C(i, j). - C(i, j) = C(i-1, j-1) + C(i-1, j), which is exactly the “sum of two elements above” rule.
These two facts give you two independent implementation strategies: build each row from the previous row, or compute each element directly from the binomial formula. Both produce the same output. The choice depends on what you need: the row-based method gives you the full triangle stored in memory, while the binomial method computes each row independently without needing to remember prior rows.
Placement coding rounds typically accept either approach. What they penalise is an off-by-one error in row count or a formatting bug that shifts the spacing.
Placement tests ask for Pascal’s triangle because it tests three skills in a single problem: understanding of recurrence relations, working with two-dimensional lists, and formatted output. A student who builds it correctly has demonstrated loops, nested indexing, and string operations. These are the same skills that appear in harder coding questions later in the same round, and getting this one right quickly buys time for what follows.
Approach 1: Building each row from the previous
The row-based method initialises every row as all-ones, then fills the interior elements using the previous row. Here is the complete implementation:
def build_pascal(n):
triangle = []
for i in range(n):
row = [1] * (i + 1) # start and end with 1
for j in range(1, i): # fill interior elements only
row[j] = triangle[i-1][j-1] + triangle[i-1][j]
triangle.append(row)
return triangle
def print_pascal(n):
triangle = build_pascal(n)
width = 2 * n - 1 # width of the widest row (single-digit numbers)
for row in triangle:
row_str = " ".join(str(x) for x in row)
print(row_str.center(width))
print_pascal(5)
Output for n=5:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Three things to verify when tracing through this code:
[1] * (i + 1)creates a list ofi+1ones. Row 0 gets[1], row 4 gets[1, 1, 1, 1, 1]before the interior fill.range(1, i)stops at indexi-1, which is one before the last element. The last element stays 1 because the initialisation already set it.triangle[i-1][j-1] + triangle[i-1][j]reads from the stored previous row. For row 4, position 2:triangle[3][1] + triangle[3][2] = 3 + 3 = 6.
The common off-by-one bug is writing range(1, i+1) instead of range(1, i). That would overwrite the last element with a computed value, breaking the boundary rule.
Approach 2: Using math.comb for each element
Python’s standard library includes math.comb(n, k), which computes C(n, k) directly. It was added in Python 3.8. The binomial approach uses this to compute every element independently:
import math
def print_pascal_binomial(n):
width = 2 * n - 1
for i in range(n):
row = [math.comb(i, j) for j in range(i + 1)]
row_str = " ".join(str(x) for x in row)
print(row_str.center(width))
print_pascal_binomial(5)
The output is identical to Approach 1:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
math.comb handles large values correctly because Python integers have arbitrary precision: there is no integer overflow at row 30, row 100, or row 1000. The values grow large (C(100, 50) has 30 digits), but Python stores them exactly. You do not need to worry about modular arithmetic unless the problem statement explicitly asks for it.
Comparing the two approaches:
| Property | Row-based | math.comb |
|---|---|---|
| Stores full triangle | Yes (triangle list) | No (prints row-by-row) |
| Space for n rows | O(n²) elements | O(n) per row |
| Depends on prior rows | Yes | No |
| Minimum Python version | Any | Python 3.8+ |
| Readable in an interview | Yes | Yes |
For placement coding rounds, either approach is correct. The row-based version is slightly more common as a question target because it tests whether you understand the recurrence relation directly.
Centred output formatting
Both implementations above use row_str.center(width) where width = 2 * n - 1. This works cleanly for single-digit values (rows 0 through 8 of Pascal’s triangle). When values exceed one digit, the spacing formula needs adjustment.
For the standard interview question (print n rows for n up to about 8), 2 * n - 1 is correct. Tracing row widths for n=5:
- Row 0:
"1"is 1 character."1".center(9)adds 4 spaces on each side. - Row 1:
"1 1"is 3 characters."1 1".center(9)adds 3 spaces on each side. - Row 4:
"1 4 6 4 1"is 9 characters."1 4 6 4 1".center(9)adds 0 spaces.
If values are two digits (row 10 of Pascal’s triangle has the element 45), the fixed-width approach breaks. A more general centering strategy uses the width of the last row’s string as the target width, rather than a formula. That generalisation is worth knowing for follow-up questions in technical interviews.
Pascal’s triangle values in placement aptitude
The numbers in Pascal’s triangle are C(n, r) values. Every combinations question in the quantitative aptitude section uses these. When a question asks “in how many ways can a committee of 3 be chosen from a group of 5”, the answer is C(5, 3) = 10, which is the element at row 5, position 3 of Pascal’s triangle.
This makes Pascal’s triangle directly useful as a lookup table for small nCr values during mental calculation. Row 4 gives you C(4,0) through C(4,4): 1, 4, 6, 4, 1. Row 5 gives 1, 5, 10, 10, 5, 1. Memorising the first six or seven rows covers most combination values that appear in aptitude tests under time pressure.
Probability questions often involve binomial distributions, where the coefficients are again C(n, r). Knowing that C(6, 2) = 15 and C(6, 3) = 20 (row 6: 1, 6, 15, 20, 15, 6, 1) removes the arithmetic bottleneck during a timed test.
One more pattern that appears in quant questions: the third diagonal of Pascal’s triangle (0-indexed) reads 1, 3, 6, 10, 15, 21. These are the triangular numbers, equal to n*(n+1)/2 for each n. Questions on handshakes, pairings, and sums of arithmetic series often reduce to values from this diagonal. Recognising the diagonal saves the derivation step during a timed test.
For a systematic approach to aptitude test mathematics, the time and work aptitude guide covers ratio-based reasoning that pairs with combinatorics in most quantitative sections. If you’re looking at which resources to prioritise, best books for placement preparation lists the standard references that cover both combinatorics and coding. Companies like D.E. Shaw test quantitative reasoning heavily; the D.E. Shaw campus recruitment process has specific aptitude patterns worth reviewing that draw on exactly this overlap between combinatorics and programming ability.
The C(n, k) recurrence that generates Pascal’s triangle is also the foundation of dynamic programming: the recurrence dp[i][j] = dp[i-1][j-1] + dp[i-1][j] is a direct translation of the construction rule. If you find yourself solving grid-path counting problems, Pascal’s triangle is often the analytical shortcut.
Building Pascal’s triangle in Python and working through C(n, k) values by hand are two activities that reinforce each other. The coding exercise makes the formula concrete; the aptitude practice makes the numbers familiar. TinkerLLM at ₹299 gives you a Python sandbox where you can extend these implementations: generating Pascal’s triangle modulo a prime, visualising it as a binary heatmap, or computing the number of odd entries per row. These are the same patterns that show up as algorithmic extensions once the basic implementation is solid.
Primary sources
Frequently asked questions
How many rows of Pascal's triangle can Python handle?
Python integers have arbitrary precision, so there is no overflow limit. You can generate thousands of rows; the only constraint is memory and time.
What is the difference between the row-based approach and math.comb?
Row-based stores all previous rows and builds each new row by summing adjacent elements. math.comb computes each element directly from the binomial formula C(i, j) without needing prior rows.
Which approach is faster for large n?
For large n, math.comb is faster per element since it avoids storing the entire triangle. For small n (under 20 rows), the difference is negligible.
Can Pascal's triangle be printed recursively in Python?
Yes, but recursion is rarely used in practice because it recomputes elements repeatedly without memoisation. The row-based loop approach is cleaner and avoids recursion depth limits.
What is the formula for any element of Pascal's triangle?
Element at row i, column j (both zero-indexed) equals C(i, j), which is i factorial divided by the product of j factorial and (i minus j) factorial.
Why does each row start and end with 1?
C(i, 0) and C(i, i) both equal 1 for any i. Geometrically, every boundary element of the triangle has no two elements above it to sum, so it defaults to 1.
A self-paced playground for building with LLMs.
TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.
Try TinkerLLM (₹299 launch)