Morgoth Morgoth - 3 months ago 27
Python Question

Kind of pyramid numbers pattern exercise

Can you help to simplify this code and make it more efficient? Mine seems like it's not the best version; what can I improve?

1
232
34543
4567654
567898765
678901109876


This is the code I made:

c = -1

for y in range(1, 7):
print()
print((6-y) * " ", end="")
c += 1

for x in range(1, y+1):
print(y%10, end="")
y += 1

while y - c > 2:
print(y-2, end="")
y -= 1

Answer

First of all, I'm guessing that you didn't really want to print that y value of 10; that you really wanted the base-10 reduction to 0. Note that you have an extra character in the pyramid base.

Do not change the value of a loop parameter while you're inside the loop. Specifically, don't change y within the for y loop.

Get rid of c; you can derive it from the other values.

For flexibility, make your upper limit a parameter: you have two constants (6 and 7) that depend on one concept (row limit).

Here's my version:

row_limit = 7

for y in range(1, row_limit):
    print()
    print((row_limit-y-1) * " ", end="")

    for x in range(y, 2*y):
        print(x%10, end="")

    for x in range(2*(y-1), y-1, -1):
        print(x%10, end="")

print()

Output:

     1
    232
   34543
  4567654
 567898765
67890109876

If you really want to push things, you can shorten the loops with string concatenation and comprehension, but it's likely harder to read for you.

for y in range(1, row_limit):
    print()
    print((row_limit-y-1) * " " + ''.join([str(x%10) for x in range(y, 2*y)]) + \
              ''.join([str(x%10) for x in range(2*(y-1), y-1, -1)]), end="")

print()

Each of the loops is turned into a list comprehension, such as:

[str(x%10) for x in range(y, 2*y)]

Then, this list of characters is joined with no interstitial character; this forms half of the row. The second half of the row is the other loop (counting down). In front of all this, I concatenate the proper number of spaces.

Frankly, I prefer my first form.