Skip to content
Advertisement

Number Pyramid Nested for Loop

I’m wondering if you could help me out. I’m trying to write a nested for loop in Python 3 that displays a number pyramid that looks like;

                              1
                         1    2   1
                     1   2    4   2   1
                 1   2   4    8   4   2   1
             1   2   4   8   16   8   4   2  1
          1  2   4   8  16   32  16   8   4  2  1
       1  2  4   8  16  32   64  32  16   8  4  2  1
    1  2  4  8  16  32  64  128  64  32  16  8  4  2  1

Can anybody help me out? It would be much appreciated!

This is what I have so far:

col = 1

for i in range(-1, 18, col*2):        

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

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

    print()   

So, I can only get half of the pyramid to display.

I guess the main problems I’m having is:

How do i get the output to display an increasing and then decreasing value (ie. 1, 2, 4, 2, 1)?

Advertisement

Answer

An alternate way using list comprehensions.

Always break the problem down into digestable chunks. Each line is a mirror of itself, so lets just deal with first making out set of numbers we need.

This generates a list of strings that hold all powers of two which is what this is generating

lines = []
for i in range(1,9):
  lines.append([str(2**j) for j in range(i)])

But if we just print this list, a) its going to only have half, and b) its going to mush the numbers together. We need to buffer the numbers with spaces. Fortunately, the last row will have the largest digits for any column, so:

Firstly, how long does each line need to end up being (we need this later) and also, what is the longest number in each column. We can use len as we cast the numbers to strings above.

b = len(lines[-1])
buffers = [len(x) for x in lines[-1]]

Now I have everything I need to print the strings (we stopped using numbers above):

So, for each line, find out how long it is, and expand the array it to the length of the longest line by filling the left of the array with empty strings (for this we’re still pretending we’re only printing the left half of the triangle):

for line in lines:
  l = len(line)
  line = [" "]*(b-len(line)) + line

With each line now buffered, we’ll make a new array that we will print from. By zip()ing together the line and the buffer, we can easily right justify (String.rjust()) numberic strings, expanded out to the length required.

  out = []
  for x,y in zip(line,buffers):
    out.append(x.rjust(y))

Remmeber until now, we’ve still just been working with the left half of the pyramid. So we take the output array, reverse it (array[::-1]) and then take every element but the first (array[1:]) and join it all together with a string and print it out.

  print(" ".join(out+out[::-1][1:]))

Voila! The completed code:

lines = []
for i in range(1,9):
  lines.append([str(2**j) for j in range(i)])

b = len(lines[-1])
buffers = [len(x) for x in lines[-1]]

for line in lines:
  l = len(line)
  line = [" "]*(b-len(line)) + line
  out = []
  for x,y in zip(line,buffers):
    out.append(x.rjust(y))
  print(" ".join(out+out[::-1][1:]))

Output:

                   1                 
               1   2  1              
            1  2   4  2  1           
         1  2  4   8  4  2  1        
      1  2  4  8  16  8  4  2 1      
    1 2  4  8 16  32 16  8  4 2 1    
  1 2 4  8 16 32  64 32 16  8 4 2 1  
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement