The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Start with [1], print the current row, then build the next row by adding adjacent values with zeroes at the edges. This simple row-by-row method prints Pascal’s Triangle without storing previous rows.
Print the triangle one row at a time
Each row begins and ends with 1. Every value between them is the sum of the two values directly above it. For example, the middle values in [1, 2, 1] combine to make the next row, [1, 3, 3, 1].
Here is a complete function that prints each row using Python list notation:
def print_pascals_triangle(rows: int) -> None:
if not isinstance(rows, int) or isinstance(rows, bool):
raise TypeError("rows must be an integer")
if rows < 0:
raise ValueError("rows must be zero or greater")
row = [1]
for _ in range(rows):
print(row)
row = [left + right for left, right in zip([0] + row, row + [0])]
print_pascals_triangle(5)
Output:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
The argument is the number of rows to print, not the index of the last row. A value of 5 prints five rows, beginning with the single-value top row. A value of 0 prints nothing; negative values are rejected instead of silently producing confusing output.
#1 Best Overall
Why the zero padding works
The expression [0] + row puts a zero before the current row, while row + [0] puts one after it. Pairing those lists lines up each value with its neighbor. For [1, 2, 1], the padded lists are [0, 1, 2, 1] and [1, 2, 1, 0]. Adding corresponding entries gives [1, 3, 3, 1]. The zeroes make the edge values remain 1 without a special case.
An explicit-loop version
If you are learning how the adjacent additions work, write out the loop instead of using a list comprehension:
def print_pascals_triangle(rows: int) -> None:
if not isinstance(rows, int) or isinstance(rows, bool):
raise TypeError("rows must be an integer")
if rows < 0:
raise ValueError("rows must be zero or greater")
row = [1]
for _ in range(rows):
print(row)
padded = [0] + row + [0]
next_row = []
for i in range(len(padded) - 1):
next_row.append(padded[i] + padded[i + 1])
row = next_row
print_pascals_triangle(5)
Both implementations use the same recurrence. In either one, assign a newly built list to row; do not overwrite values in the current row while also using them to calculate the next one.
Rank #2
Or skip the browser setup
Pascal’s Triangle is generated locally by the Python code above; a screenshot API does not calculate it. If you also need a website screenshot from Python, ScreenshotNeo offers a one-request screenshot API. The example below captures https://python.org as a WebP image. See the ScreenshotNeo API documentation for request options.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://python.org"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
ScreenshotNeo removes known cookie or consent banners, newsletter popups and chat widgets before capture; those cleanup steps can be turned off. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides screenshot tools for AI agents. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. See ScreenshotNeo or sign up for the free plan.
Generate rows for reuse or centered output
Printing each row directly is convenient, but it couples generation to display. If another part of a program needs to inspect, format, or test the rows, make a generator that yields them:
def pascal_rows(rows: int):
if not isinstance(rows, int) or isinstance(rows, bool):
raise TypeError("rows must be an integer")
if rows < 0:
raise ValueError("rows must be zero or greater")
row = [1]
for _ in range(rows):
yield row
row = [left + right for left, right in zip([0] + row, row + [0])]
for row in pascal_rows(5):
print(row)
Each yielded row is a list. The generator then rebinds row to a new list, so the row already yielded is not changed by the next iteration. To keep every row for later use, materialize the generator with list(pascal_rows(5)).
Print a centered visual triangle
print(row) displays list brackets and commas; it does not create a centered triangle. For a visual layout, convert the values to text, join them with spaces, and center each line against the widest line. The following code also handles rows=0:
Free tools Windows power users keep installed
One-click scans. No signup required.
def print_centered_pascals_triangle(rows: int) -> None:
data = list(pascal_rows(rows))
if not data:
return
lines = [" ".join(map(str, row)) for row in data]
width = max(map(len, lines))
for line in lines:
print(line.center(width))
print_centered_pascals_triangle(5)
The output is a text approximation of a triangle:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Centering is most reliable in a monospaced terminal or code block. The spaces separate numbers, but the values do not occupy equal character widths once they have different numbers of digits, so large triangles may not look perfectly symmetrical. This changes only presentation; the generated values are the same.
Choose between streaming and storing
The right implementation depends on whether the program only needs to display rows or needs to revisit them.
| Approach | Best for | Retained row data | Trade-off |
|---|---|---|---|
| Print each row as it is generated | Plain list output when no later formatting is needed | O(n) working data for the current and next row | Uses less memory, but does not keep earlier rows |
| Yield rows from a generator | Processing rows one at a time in another function | O(n) working data, excluding anything the caller stores | Flexible and streamable; a second pass requires generating the rows again unless the caller stores them |
| Materialize all rows | Centered formatting, indexing, or repeated use | O(n²) data across all rows | Convenient for later access, with more memory as the row count grows |
Here, n means the requested number of rows. Each new row contains one more value than the previous one, so generating n rows performs a quadratic number of additions overall. The count describes additions, not their exact running time: Python integers can grow in size, so arithmetic on very large values takes more work than arithmetic on small ones. Printing or formatting also takes time proportional to the output produced.
Centered output needs the width of the widest line before printing the first line. Storing the rows, as in the example, makes that easy. For a very large triangle where retaining all rows is undesirable, generate the rows once to determine the width, then generate them again to print. That trades a second pass of additions for lower retained memory.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchCheck the result and troubleshoot mistakes
- The top row is missing or values are wrong: initialize with
[1], not an empty list. The first row is the starting point for the recurrence. - The edge values disappear: add zero padding on both ends before pairing adjacent values. Without it, the next row has no outer pair to produce each edge
1. - A row contains unexpected values: build a fresh next-row list from the unchanged current row, then replace the current row. Updating a list in place while reading it mixes values from different rows.
- The output has brackets and commas: that is what
print(row)does for a Python list. Join string representations of values with spaces when you want plain text, and usecenter()for line alignment. - There is no output: check whether the requested count is zero. Zero rows is valid in the provided functions and intentionally prints nothing.
- A negative count does not make sense for your program: reject it explicitly, as these examples do with
ValueError. If you obtain the count from user input, convert the input to an integer and handle invalid text before calling the function. - A count such as
5.0is rejected: it is a float, not an integer argument. Supply an integer row count; the examples also reject booleans rather than treatingTrueas one row.
Test the behavior you depend on
A small test checks the first rows, the row count, and the boundaries. These checks can be run after defining pascal_rows:
Best Value
expected = [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
]
actual = list(pascal_rows(5))
assert actual == expected
assert len(actual) == 5
assert all(row[0] == 1 and row[-1] == 1 for row in actual)
assert list(pascal_rows(0)) == []
These assertions check both the known sample and two useful interface expectations: requesting five rows returns five, while requesting zero returns an empty sequence.
When the row method is the right fit
The row-list approach directly mirrors the defining rule: edges are ones, and interior values come from adjacent values above. It is a practical default for printing, learning, and modest row counts. Use the generator when you want to separate calculation from output; keep a list of all rows only when later access or a centered first pass justifies the additional storage.
Frequently Asked Questions
Why is the first row written as [1]?
It is the starting row: with no preceding values, the triangle begins with a single 1.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteDoes this function return a list of all rows?
The printing function writes rows to the console and returns None. Use list(pascal_rows(n)) when you need a reusable collection.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

