Left-Aligned Descending Number Triangle in Python

Beginner
⏱️ 7 min read
📚 Updated: Sep 2026
🎯 3 Code Examples
🚀 Live Preview
Nested Loops + range()

What You’ll Learn

The left-aligned descending number triangle prints 54321, 5432, 543, 54, 5 — a natural step after the reverse descending triangle in Program 3. This tutorial covers a fixed inner start with shrinking stop, nested loops, a live preview, algorithm steps, worked Python examples, edge cases, and complexity.

Shape Rule

Fixed start, shrinking stop

Row 1 prints 54321, row 2 prints 5432, shrinking until a single 5 — every row starts at rows.

Outer Loop

0..rows-1

for i in range(0, rows): changes the inner loop’s stop point each row.

Inner Loop

rows..i descending

for j in range(rows, i, -1): always starts at rows and counts down.

print end= vs print()

Same line / next line

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

Live Preview

3–9 rows

Pick a row count and draw the left-aligned descending triangle in the browser.

O(n²)

Complexity

Total digit prints = n(n+1)/2; extra memory stays O(1).

Introduction

A left-aligned descending number triangle prints every row starting from rows and counting down, but each next row stops earlier. With rows = 5, the output is 54321, 5432, 543, 54, 5.

In Python the outer loop runs i = 0..rows-1, the inner loop prints j from rows down to i+1 via range(rows, i, -1), then print() moves to the next line.

Why it matters?

It teaches fixed-start inner loops with a changing stop — a key step after Program 3’s reverse descending rows.

Key Highlights

Fixed start

Inner loop always begins at rows.

Shrinking stop

Outer loop changes where the inner loop stops.

vs Program 3

Program 3 shifts the start each row; Program 4 keeps the same first digit.

Series Foundation

Follow Program 3; continue to Program 5 (ascending triangle) next.

In short: for each i from 0 to rows-1, print j from rows down to i+1, then print().

📝 Problem & Approach

Given a positive integer rows (e.g. 5), print a left-aligned descending triangle: each row starts at rows and counts down, with the outer loop shortening the stop point each line.

Python
# rows = 5 (conceptual shape)
# 54321
# 5432
# 543
# 54
# 5

Inputs & Outputs

ItemTypeDescription
rowsintMaximum digit and number of triangle lines.
iintOuter loop — row index from 0 to rows-1; controls inner stop.
jintInner loop — descending from rows down to i+1.

Minimal workflow

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

Approach comparison

ApproachIdeaBest for
Nested loops54321, 5432, …Learning and interviews
User-input rowsint(input(...))Flexible console programs
Spaced outputprint(j, end=" ")Easier reading per row

⚡ Quick Reference

GoalPattern
Walk rowsfor i in range(0, rows):
Print digits rows..i+1for j in range(rows, i, -1): print(j, end="")
End the rowprint()
Spaced digitsprint(j, end=" ")
User inputint(input(...))
Program 3 contrastfor i in range(rows, 0, -1): with j = i..1

📋 Fixed Rows vs User Input vs Spaced Output

Same left-aligned descending triangle — different ways to control rows and formatting.

Outer loop
i = 0..rows-1

Changes inner stop each line

Inner loop
j = rows..i+1

Fixed start, descending digits

First row
i = 0

Longest row on top

Learning tip
range stop

Remember range stop is exclusive

Context

When This Pattern Shows Up

Reach for this pattern when teaching fixed-start inner loops and shrinking row lengths.

  1. After Program 3

    Natural follow-up — every row keeps the same starting digit while the stop point shrinks.

  2. Nested-loop warm-up

    Outer/inner bound practice with an immediate visual check.

  3. Console I/O practice

    Combine loops with input() for a flexible row count.

  4. Gateway to variants

    Compare Program 3 (reverse descending) and Program 5 (ascending triangle) next.

  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 nested loops, output sequencing, and O(n²) thinking.

🔮 Live Preview

Choose a row count between 3 and 9 and draw the left-aligned descending 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 spaced output variant. Click View Output to reveal sample console results.

📚 Getting Started

Print five rows of the left-aligned descending triangle with nested loops.

Example 1 — Fixed rows = 5

Hard-coded row count — ideal for first demos and screenshots.

Python
rows = 5

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

How It Works

When i = 0, the inner loop prints 5, 4, 3, 2, 1 — output 54321. When i = 4, only one digit prints — output 5. The outer loop increases i each row, shortening the inner loop.

📈 User Input

Read the row count with input() instead of hard-coding 5.

Example 2 — User Input

Read rows with input() and int() (wrap in try/except ValueError in real apps).

Python
rows = int(input("Enter the number of rows: "))

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

How It Works

Same fixed-start inner-loop core as Example 1; only the source of rows changes from a literal to user input. Non-numeric input raises ValueError with bare int(input()) — use try/except for safer labs.

⚡ Spaced Output

Add a space between digits for easier reading on each row.

Example 3 — Spaced Digits

Keep rows = 5 but print each digit followed by a space.

Python
rows = 5

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

How It Works

Only the print statement changes — print(j, end=" ") instead of print(j, end=""). Loop bounds stay the same as Example 1.

🧠 How the Algorithm Prints Rows

1

Set up

No imports needed for fixed rows; use input() when reading. Set rows = 5 and loop variables i, j.

Setup
2

Outer loop walks rows

for i in range(0, rows): — ascending outer loop changes the inner stop each row.

Row
3

Inner loop (j)

for j in range(rows, i, -1): — always starts at rows and counts down.

Digits
4

New line

print() ends the row after the inner loop finishes.

Break
=

Left-aligned descending triangle complete

Each row starts at rowsO(n²) time, O(1) extra memory.

🔎 Worked Walkthrough — rows = 5

Trace each outer-loop value of i, the inner-loop range, digit count, and full row output.

iInner loop (j)PrintsRow output
05, 4, 3, 2, 1554321
15, 4, 3, 245432
25, 4, 33543
35, 4254
4515

Prints per row = rows - i — total prints = n(n+1)/2 for n rows.

Use Cases

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

1. Teaching Nested Loops

Clearest visual proof that outer and inner bounds interact.

Example: flip j-- to j++ and watch digit order change.

2. Pattern Series Base

Foundation for inverted, pyramid, diamond, and hollow variants.

Example: continue to Program 5 for an ascending number triangle.

3. Console Formatting Drills

Practice print vs row newline without complex math.

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

4. Spaced Output

Add spaces between digits once the two-loop structure works.

Example: use print(j, end=" ") between digits on each row.

5. Complexity Intuition

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

Example: count printed digits for rows = 5 — total is 15 (5+4+3+2+1).

6. Input Validation Labs

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

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

Pro Tip: when an interviewer asks for patterns, explain the outer/inner roles first — then write the loops. The story matters as much as the code.

Advantages

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

  1. 1. Instant Visual Feedback

    Wrong bounds show up immediately as a broken staircase.

  2. 2. Minimal Concepts

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

  3. 3. Easy to Extend

    Invert, center, hollow, or change the fill character 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 shortens by one digit.

Usage Tips

Small habits that keep number-pattern code clean.

  1. 1. Remember range() Stop Is Exclusive

    Outer loop uses range(0, rows); inner loop uses range(rows, i, -1) — the stop value is not included.

  2. 2. Call try/except ValueError

    Use try/except ValueError so bad input does not crash when converting rows.

  3. 3. Keep print() Outside the Inner Loop

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

  4. 4. Fixed Inner Start

    for j in range(rows, i, -1): always begins at rows — only the stop changes.

  5. 5. Dry-Run rows = 3

    Trace i = 0, 1, 2 on paper before coding the full rows = 5 demo.

Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put print() inside the inner loop.

Common Pitfalls

Mistakes that commonly break left-aligned descending number triangles.

  1. 1. Newline Inside the Inner Loop

    Each digit lands on its own line — you get a column, not a triangle.

    → Use print(j, end="") for digits; print() only after the inner loop.

  2. 2. Wrong Inner Stop

    range(rows, 0, -1) on every row prints a full rectangle — the stop must change with i.

    → Keep for j in range(rows, i, -1): so each row shortens correctly.

  3. 3. Descending Outer Loop by Mistake

    for i in range(rows, 0, -1): with range(i, 0, -1) gives Program 3’s shape, not this one.

    → Use for i in range(0, rows): with range(rows, i, -1).

  4. 4. Forgetting the Row Break

    Omitting print() glues every digit onto one endless line.

    → Always end the row after the inner loop.

  5. 5. Bare int(input())

    Letters or empty input raise ValueError with bare int(input()).

    → Catch ValueError and re-prompt on failure.

Edge Cases

Check these inputs before calling the solution done.

rows = 1

Single digit row

Output is just the digit rows on one line.

rows = 0

Empty pattern

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

Negative

rows < 0

Treat as invalid; re-prompt instead of silent empty output.

rows = 2

Smallest triangle

Two rows: 21 and 2.

Bad input

Non-numeric input

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

Large rows

Large row count

Each row prints rows - i digits — total work grows as n(n+1)/2.

🎯 Practice Problems

Try these variations to lock in the pattern.

1. Reverse descending triangle

  • Outer loop counts down; inner prints i..1
  • Review Program 3

2. Ascending triangle

  • Continue with Program 5
  • Inner loop prints 1..i on each row

3. Right-aligned variant

  • Add leading spaces before each row
  • Same loops, padded output

4. Spaced output

  • Use print(j, end=" ") between digits
  • Same loops, wider visual spacing

Notes

  • Fixed start rule. Outer loop: i = 0..rows-1. Inner loop: j = rows..i+1 via range(rows, i, -1).
  • print(j, end="") stays on the line; print() advances — mix them carefully.
  • Validate rows > 0 for interactive programs; rows = 1 should print a single digit matching rows.
  • Every row starts at rows — compare with Program 3 where the start digit shifts each row.

Quick Takeaway: outer loop i = 0..rows-1, inner loop range(rows, i, -1) with print(j, end=""), then print().

⏱️ Time and Space Complexity

ProgramTimeExtra space
Nested loops (Examples 1–3)O(n²)O(1)
Smaller demo (Example 3)O(n²)O(1)
Wrap Up

🎉 Conclusion

The left-aligned descending number triangle is a compact nested-loop lesson: a fixed inner start at rows with a shrinking stop on each row. Master the fixed-rows version, then try user input and spaced output.

Practice the three examples above, then continue to Program 5 for the ascending number triangle.

Every row starts at rows — keep print(j, end="") for digits and print() for the break.

💡 Best Practices

✅ Do

  • Use for i in range(0, rows): in the outer loop
  • Inner: for j in range(rows, i, -1): always starts at rows
  • Use print(j, end="") for digits and print() after each row
  • Validate rows ≥ 1 for interactive programs
  • Wrap int(input()) in try/except ValueError

❌ Don’t

  • Call print() inside the inner digit loop
  • Use range(rows, 0, -1) for the outer loop (that is Program 3)
  • Forget that range() stop is exclusive
  • Ignore bad console input in user-facing demos
  • Skip the rows = 1 edge case

Key Takeaways

Knowledge Unlocked

Five things to remember about this left-aligned descending triangle

Print the pattern the beginner-friendly way.

5
Core concepts
02

Outer loop

range(0, rows)

Code
03

Inner loop

range(rows, i, -1)

Code
04

Newline

Ends each row

Shape
O 05

Complexity

O(n²) time

Analysis

❓ Frequently Asked Questions

Because the inner loop always begins at rows (the maximum digit) and counts down. Only the stopping point i changes per row.
Row i (0-based) prints rows - i digits — the inner loop runs range(rows, i, -1).
Program 3 prints i..1 with a descending outer loop (4321, 321, ...). Program 4 prints rows..i with an ascending outer loop — every row starts at rows.
No — digits are left-aligned with no leading spaces. Each row begins flush left at the maximum digit.
Replace 5 with rows in the outer loop bound — see Example 2.
Use print(j, end=" ") instead of print(j, end="") — see Example 3.
O(n²) for n rows because total prints are 1 + 2 + ... + n = n(n+1)/2.
Use a try/except ValueError around int(input()) or check the raw string with .isdigit() before converting so bad input does not crash the script.
Only one row prints — a single digit matching rows.

Did you Know? 🔊

Each row starts at rows and counts down to a shrinking limit. Row i prints rows - i digits — total prints = n(n+1)/2; output is left-aligned with no leading spaces.

Continue to Program 5

Move on to the ascending number triangle in the Python number-pattern series.

Program 5 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.

12 people found this page helpful