Reverse Row Number Triangle in Python

Beginner
⏱️ 8 min read
📚 Updated: Aug 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops

What You’ll Learn

Program 7 prints a reverse row number triangle: each row shows digits from the current row index down to 11, 21, 321, and so on. This tutorial covers the shape rule, ascending outer loop, inner countdown i..1, a live preview, worked Python examples, edge cases, and complexity.

Shape Rule

i..1 per row

Row with outer i = 1 prints 1; row with i = 5 prints 54321 — digits grow from the right.

Outer Loop

i = 1..rows

for i in range(1, rows + 1) — row width increases from one digit to rows digits.

Inner Loop

j = i..1

for j in range(i, 0, -1) prints digits in reverse order on each row.

print() vs end

Same line / next line

Digits use print(j, end=""); end each row with print().

Live Preview

rows = 3..9

Pick row count and draw the reverse row triangle in the browser.

O(n²)

Complexity

Total prints = 1+2+…+n = n(n+1)/2 — a triangular number.

Introduction

A reverse row number triangle grows digits from the right: each row prints numbers from the current row index down to 1. With rows = 5, you get 1, 21, 321, 4321, 54321.

In Python use an outer loop counting up from 1 to rows, an inner loop printing j from i down to 1, then print() after each row.

Why it matters?

It pairs with Program 6’s left-growing triangle — the inner loop counts down instead of up, teaching reverse iteration.

Key Highlights

Outer up

i = 1..rows — narrow row first.

Inner i..1

Countdown from i to 1.

vs Program 6

Program 6 outer down, inner i..rows; Program 7 outer up, inner i..1.

Series Step

Follow Program 6; continue to Program 8 next.

In short: outer i = 1..rows, inner j = i..1, print(j, end="") per digit, then print().

📝 Problem & Approach

Given row count rows = 5, print a reverse row number triangle — row outer index i shows digits i..1.

Python
# rows = 5
#1
#21
#321
#4321
#54321

Inputs & Outputs

ItemTypeDescription
rowsintTriangle height — also the widest row digit count.
i (outer)intCurrent row index — runs 1 up to rows.
j (inner)intPrints i..1 with print(j, end="").
Row widthintRow with outer i prints exactly i digits.
First rowintSingle digit 1 when i = 1.
Last rowstringDigits rows..1 when i = rows.

Minimal workflow

Pseudocode
for i from 1 to rows:
    for j from i down to 1:
        print j
    print newline

Approach comparison

ApproachIdeaBest for
Ascending outerfor i in range(1, rows + 1)Narrow-first row order
Inner i..1Countdown from i to 1Right-growing triangle
User-input rowsint(input())Flexible height
Compact tracerows = 3 on paper firstQuick dry-runs
Spaced outputprint(j, end="")Readable columns

⚡ Quick Reference

GoalPattern
Outer loopfor i in range(1, rows + 1)
Inner loopfor j in range(i, 0, -1): print(j, end="")
End rowprint()
Program 6 contrastProgram 6: outer down, inner i..rows; Program 7: outer up, inner i..1

📋 Fixed Rows vs User Input vs Compact Trace

Same reverse row triangle — three ways to set row count and trace the logic.

Fixed rows
rows = 5

Hard-coded height for demos

User input
int(input())

Read row count from console

Compact trace
rows = 3

Quick dry-run on paper

Outer
i = 1..rows

Ascending row index

Inner
j = i..1

Countdown per row

Context

When This Pattern Shows Up

Reach for this pattern when teaching ascending outer loops, inner countdown, and comparing shapes with Program 6.

  1. Post Program 6 exercise

    Natural companion to Program 6 — same triangular print count, inner loop counts down instead of up.

  2. Reverse counting drills

    Inner loop j-- from i to 1 — essential countdown practice.

  3. Interview warm-ups

    Classic nested-loop question — explain outer up, inner countdown before coding.

  4. Gateway to Program 8

    Compare this right-growing triangle with the next pattern in the series.

  5. Not a UI layout tool

    This is a console teaching pattern — not how you build modern app screens.

Key benefit: one small program that locks in ascending outers, inner countdown, and O(n²) thinking.

🔮 Live Preview

Choose a row count between 3 and 9 and draw the reverse row number triangle in the browser.

Try 4, 5, or 7. Max up to 9 in this preview.

Live result
Press "Draw pattern".

Examples Gallery

Three complete Python programs — fixed rows, user input, and a compact trace with rows = 3. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows of the reverse row number triangle with nested loops.

Example 1 — Fixed rows = 5

Hard-coded height — outer loop up, inner loop counts down each row.

Python
rows = 5

for i in range(1, rows + 1):
    for j in range(i, 0, -1):
        print(j, end="")
    print()

How It Works

Outer i runs 1 to 5 — inner j prints i down to 1 on each row.

📈 Practical Variant

Read row count from the user with validation.

Example 2 — User Input Rows

Configurable height with int(input()) and a positive-rows check.

Python
try:
    rows = int(input("Enter the number of rows: "))
    if rows <= 0:
        raise ValueError
except ValueError:
    print("Please enter a positive integer.")
else:
    for i in range(1, rows + 1):
        for j in range(i, 0, -1):
            print(j, end="")
        print()

How It Works

Same nested loops — only the row count comes from console input with safe parsing.

⚡ Compact Trace

Use rows = 3 for a quick paper trace before larger triangles.

Example 3 — Compact rows = 3 Trace

Small triangle — easy to dry-run on paper before scaling up.

Python
rows = 3

for i in range(1, rows + 1):
    for j in range(i, 0, -1):
        print(j, end="")
    print()

How It Works

Three rows, six total digits — trace i and j on paper before coding rows = 5.

🧠 How the Nested Loops Build Each Row

1

Choose the row count

int rows = 5; sets how many rows to print.

Setup
2

Outer loop (row index)

for i in range(1, rows + 1) moves from row 1 to row 5.

Row control
3

Inner loop (print i..1)

for j in range(i, 0, -1) prints digits in reverse order for each row.

Reverse print
4

New line

print() moves to the next row after each line is printed.

Line break
=

Reverse row triangle complete

Total printed digits follow triangular numbers: n(n+1)/2, so time complexity is O(n²).

🔎 Worked Walkthrough — rows = 5

Trace each row — outer i sets width, inner j counts down from i to 1.

Row (i)Inner j valuesOutput line
111
22, 121
33, 2, 1321
44, 3, 2, 14321
55, 4, 3, 2, 154321

Total digits printed: 1+2+3+4+5 = 15 = 5×6/2 — the fifth triangular number.

Use Cases

Where this tiny pattern (and its countdown inner loop) shows up beyond the homework prompt.

1. Teaching Countdown Loops

Inner j-- from i to 1 — concrete reverse iteration practice.

Example: trace row 3 and watch j print 3, 2, 1.

2. Pair with Program 6

Program 6 grows digits from the left; Program 7 grows from the right — same O(n²) total.

Example: print both patterns side by side for rows = 5.

3. Output Formatting Drills

Practice print(j, end="") vs print() without complex math.

Example: put print() inside the inner loop by mistake.

4. Character Substitution

Swap digits for letters, stars, or spaced output once the loop works.

Example: print j + " " for spaced digits on each row.

5. Complexity Intuition

Triangular totals make O(n²) concrete for beginners.

Example: count printed digits for n = 10 → 55.

6. Input Validation Labs

Pair the pattern with int(input()) and positive-row checks.

Example: reject rows <= 0 and re-prompt.

Pro Tip: when an interviewer asks for patterns, explain outer up and inner countdown first — then write the loops.

Advantages

Why this pattern earns a permanent spot in beginner Python courses.

  1. 1. Instant Visual Feedback

    Using j++ instead of j-- shows up immediately as wrong row order.

  2. 2. Minimal Concepts

    Only loops and console output — no arrays or math libraries.

  3. 3. Easy to Extend

    Add spaces, right-align, or swap digits for stars with small edits.

  4. 4. O(1) Extra Memory

    Streaming output needs no storage beyond loop counters.

Pro Tip: trace i and j on paper for rows = 3 before coding — watch how each row adds one digit on the right.

Usage Tips

Small habits that keep reverse-row triangle code clean.

  1. 1. Name Bounds Clearly

    Use rows (or n) and keep i/j for row/column loops.

  2. 2. Prefer try/except

    Avoid crashes when the user types letters instead of a number.

  3. 3. Keep Newline Outside

    Only call print() after the inner loop finishes the row.

  4. 4. Count Down on the Inner Loop

    for j in range(i, 0, -1) matches “row i prints digits i..1” naturally.

  5. 5. Dry-Run One Small n

    Trace rows = 3 on paper before coding larger demos.

Pro Tip: if rows print ascending digits (12, 123, 1234), you used j++ instead of j--.

Common Pitfalls

Mistakes that commonly break reverse row number triangles.

  1. 1. Incrementing j Instead of Decrementing

    j++ prints ascending digits per row — 12, 123, 1234 instead of 21, 321, 4321.

    → Use for j in range(i, 0, -1).

  2. 2. Forgetting Newline After Each Row

    All digits print on one long line without a row break.

    → Call print() after the inner loop.

  3. 3. Zero or Negative Rows

    Invalid input may print nothing or behave unexpectedly.

    → Validate rows > 0 before the loops.

  4. 4. Blind int(input())

    Letters or empty input raise ValueError when int(input()) is unchecked.

    → Wrap in try/except ValueError and re-prompt on failure.

  5. 5. Newline Inside Inner Loop

    Each digit prints on its own line — vertical output instead of a triangle.

    → Use print(j, end="") inside, print() outside only.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single row

Prints only 1 — inner loop runs once with j = 1.

rows = 0

Zero rows

Outer loop never runs — print nothing or show a message.

rows = 2

Minimal triangle

Output 1 then 21 — good quick test.

Negative

Negative rows

Reject with validation — outer loop condition fails silently otherwise.

Bad input

Non-numeric input

Bare int(input()) raises ValueError — use try/except.

Large n

Many rows

Still O(n²) prints — cap rows for console demos.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Compare with Program 6

  • Program 6: outer down, inner i..rows
  • Program 7: outer up, inner i..1

2. Add spaces between digits

  • Use print(j, end="")
  • Same loops, readable columns

3. Next in series

  • Continue with Program 8
  • Next number pattern in the series

4. Paper trace

  • Dry-run rows = 3 before coding
  • Fill the walkthrough table by hand

Notes

  • Row width. Row i prints exactly i digits — the triangle widens from the right.
  • Total digits = n(n+1)/2 — a triangular number. For rows = 5, that is 15 digits.
  • Program 5 prints 1..i ascending; Program 7 prints i..1 descending — mirror per-row logic.
  • The last row always shows digits from rows down to 1 — e.g. 54321 when rows = 5.

Quick Takeaway: outer i = 1..rows, inner j = i..1, print(j, end=""), then print().

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–2)O(rows²)O(1)
Compact trace (Example 3)O(rows²)O(1)
Wrap Up

🎉 Conclusion

The reverse row number triangle is a compact nested-loop exercise: outer counts up, inner counts down, and each row grows one digit wider from the right. Master the fixed rows = 5 version, then try user input with int(input()) and the compact rows = 3 trace.

Practice the three examples above, then continue to Program 8 for the next pattern in the series.

Use range(i, 0, -1) for reverse digits per row, keep print() outside the inner loop, and validate row count when reading from the console.

💡 Best Practices

✅ Do

  • Explain outer up and inner countdown before coding
  • Use for j in range(i, 0, -1)
  • Call print() after each inner loop
  • Validate rows > 0 for user input
  • Dry-run rows = 3 on paper first
  • State O(n²) time when asked about complexity

❌ Don’t

  • Use range(1, i + 1) when the pattern needs countdown
  • Put print() inside the inner loop
  • Skip input validation on console reads
  • Confuse this with Program 6’s left-growing triangle
  • Skip the rows = 3 dry-run before larger demos

Key Takeaways

Knowledge Unlocked

Five things to remember about this reverse row pattern

Print the reverse row number triangle the beginner-friendly way.

5
Core concepts
02

Outer

i = 1..rows

Loop
03

Inner

j = i..1 countdown

Loop
W 04

Output

print then newline

I/O
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

It prints a reverse row number triangle: row 1 shows 1, row 2 shows 21, row 3 shows 321, and so on until the last row shows digits from rows down to 1.
The inner loop uses range(i, 0, -1) which prints i, i-1, ..., 1 on each row.
When i = rows (5), the inner loop prints j from 5 down to 1 — giving 54321 on the last line.
Program 6 outer counts down and prints i..rows (5, 45, 345). Program 7 outer counts up and prints i down to 1 (1, 21, 321).
Program 5 prints 1..i ascending per row. Program 7 prints i..1 descending per row — digits grow from the right instead of the left.
print(j, end="") stays on the same line for each digit. print() ends the row after the inner loop finishes.
Change rows or read it from user input with int(input()) — see Example 2.
Yes — use range(1, i + 1) in the inner loop like Program 5.
O(n²) for n rows because total prints are 1 + 2 + ... + n = n(n+1)/2.
Use try/except ValueError around int(input()). Bare int(input()) raises ValueError on bad input.

Did you Know? 🔊

Each row prints digits in reverse order — outer i runs 1..rows, inner j counts down from i to 1 — producing 1, 21, 321, and so on. Total prints grow as O(n²).

Continue to Program 8

Move on to the next pattern in the Python number-pattern series.

Program 8 tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

11 people found this page helpful