Python Number Triangle Pattern (Bidirectional)

Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview

What Is This Pattern?

A bidirectional number triangle prints a repeated digit on each shrinking row — digits rise (1, 2, 3) then mirror down (2, 1).

Remember
Rule: row i repeats val, length = rows − i + 1
      val = i if i < rows − 1
          else rows + 1 − i

11111
2222
333
22
1     ← rows = 5

Shrinking length plus a mapped digit — a clear follow-up after the centered pyramid in Program 24.

How to Solve It

Outer i = 1..rows; pick the row digit; inner j = i..rows repeats that digit.

MethodIdeaBest for
if/else mappingRise then rows + 1 - iLearning, interviews
input() + expressionSame loops; generalize for any rowsInteractive practice
Spaced digitsprint(val, end=" ")Readable output

Pseudocode

Pseudocode
for i from 1 to rows:
    if i < rows - 1:
        val = i
    else:
        val = rows + 1 - i
    for j from i to rows:
        print val (same line, no spaces)
    print newline

Cheat sheet

GoalPattern
Set rowsrows = 5
Outer loopfor i in range(1, rows + 1):
Pick digitval = i if i < rows - 1 else rows + 1 - i
Shrink rowfor j in range(i, rows + 1): print(val, end="")
End rowprint()
Spacedprint(val, end=" ")

Printing Numbers vs Starting a New Line

APIEffectUse for
print(val, end="")Stays on the same line, no spaceEach repeated digit
print()Ends the current lineAfter the inner loop

Glue digits with end="", then break once with print(). Putting print() inside the inner loop prints one digit per line.

Live Preview

Change the row count and the bidirectional triangle updates instantly.

Whole numbers from 1 to 9. Tap a chip or type a value — the preview redraws as you go.

Live result 5 rows · 15 digits
11111
2222
333
22
1

Worked Walkthrough — rows = 4

Trace each i, the mapped digit, and how many times it repeats.

ivalRepeatsPrinted row
11 (i < 3)4×1111
22 (i < 3)3×222
32 (4 + 1 − 3)2×22
41 (4 + 1 − 4)1×1

The switch happens when i >= rows − 1 — that is when the digit starts mirroring down.

Python Programs

Three complete programs: fixed rows = 5, input() rows, and spaced digits. Use View Output for sample results.

Example 1 — Fixed rows = 5

Hard-coded height — if/else picks the digit; the inner loop shrinks each row.

Python
rows = 5

for i in range(1, rows + 1):
    for j in range(i, rows + 1):
        if i < 4:
            print(i, end="")
        else:
            print(rows + 1 - i, end="")
    print()

How It Works

1. Outer rows. i runs from 1 to 5 — one row per value.

2. Shrink. Inner j starts at i, so row length is rows − i + 1.

3. Map digit. When i < 4, print i; otherwise print rows + 1 − i (gives 2, then 1).

Example 2 — input() Rows

Read the row count at runtime; a conditional expression generalizes the digit mapping for any size.

Python
rows = int(input("Enter rows: "))

for i in range(1, rows + 1):
    val = i if i < rows - 1 else rows + 1 - i
    for j in range(i, rows + 1):
        print(val, end="")
    print()

How It Works

1. Read rows. Convert the prompt answer with int().

2. General mapping. i if i < rows - 1 else rows + 1 - i replaces the hard-coded i < 4.

3. Safer input tip. Bare int(input()) raises ValueError on letters. Prefer:

Safer input
raw = input("Enter rows: ").strip()
try:
    rows = int(raw)
except ValueError:
    print("Enter a positive whole number.")
    raise SystemExit(1)
if rows < 1:
    print("Enter a positive whole number.")
    raise SystemExit(1)

Example 3 — Spaced Digits

Keep rows = 5 but print a space after each digit for easier reading.

Python
rows = 5

for i in range(1, rows + 1):
    val = i if i < rows - 1 else rows + 1 - i
    for j in range(i, rows + 1):
        print(val, end=" ")
    print()

How It Works

1. Same structure. Outer loop, mapping, and shrinking inner loop match Example 2.

2. Only end= changes. Use end=" " instead of end="".

3. Same shape. Row lengths and digit values are unchanged — only spacing differs.

Edge Cases & Pitfalls

Check these before calling the solution done.

j = 1

Rows do not shrink

Starting the inner loop at range(1, rows + 1) keeps every row length rows. Use range(i, rows + 1).

hard 4

Hard-coded threshold

i < 4 only fits rows = 5. Prefer i < rows - 1 for other sizes.

print() inside

Vertical digits

If print() is inside the inner loop, each digit lands on its own line.

rows = 1

Single digit

Output is just 1 — the mirror branch still yields rows + 1 - i = 1.

rows ≤ 0

Empty output

The outer loop never runs. Guard interactive input with rows >= 1.

input()

Catch ValueError

Letters crash bare int(input()) — wrap in try/except and require rows >= 1.

Time and Space Complexity

ProgramTimeExtra space
Examples 1–3O(n²)O(1)

Total digits = n + (n−1) + … + 1 = n(n+1)/2 → O(n²).

Key Takeaways

  • Rule: shrink with j = i..rows; map digit up then down.
  • Mapping: val = i if i < rows - 1 else rows + 1 - i.
  • end= vs print(): digits stay on the line; print() advances after each row.
  • Complexity: O(n²) for n rows.

One line: shrink the row from the left, and flip the printed digit after the peak with rows + 1 − i.

Frequently Asked Questions

For i = 5 and rows = 5, the condition i < rows - 1 is false, so the program uses rows + 1 - i, which equals 1.
Because the inner loop runs from j = i to rows. As i increases, the inner loop executes fewer times.
Digits rise (1, 2, 3) on early rows then mirror down (2, 1) on the last rows via the rows + 1 - i mapping.
print(val, end="") repeats the digit on the same line. print() ends the row after the inner loop finishes.
A single inner loop with a digit mapping keeps the shrinking row logic in one place.
Use val = i if i < rows - 1 else rows + 1 - i (see Example 2).
O(n²) for n rows because total prints are triangular (n + (n-1) + … + 1).
Use try/except ValueError around int(input()) so bad input does not crash the script.
Only one row prints — a single 1.

Did you know?

This pattern prints repeated digits per row. The inner loop runs from j = i to rows, shrinking each row. The row digit is i for the first half, then switches to rows + 1 - i to produce 22 and 1.

Next: Diagonal Asterisk Pattern

Continue with the next pattern in the Python number-pattern series.

Program 26 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