Форматирование треугольника Паскаля

В настоящее время я работаю над домашним заданием по созданию в Python так называемого треугольника Паскаля.

Пока это то, что у меня есть:

def mytri(myrange):
    trianglevar = [[1]]
    for i in range(1, myrange):
        tempvar = [1]
        for n in range(0, i-1):
            tempvar.append(trianglevar[i-1][n]+trianglevar[i-1][n+1])
        tempvar.append(1)
        trianglevar.append(tempvar)
    return trianglevar

def mymenu():
    for i in mytri(int(raw_input("Please enter the height of the triangle: "))):
        print i
    print '\n'
    choicevar = raw_input("Would you like to create another triangle? (y/n): ")
    if choicevar == "y":
        mymenu()
    else:
        print "Goodbye."

mymenu()

Что программа делает до этого момента, так это выполняет расчет треугольника. Он вычисляет числа в каждой строке (начиная с 1) и останавливается после достижения количества строк, указанного пользователем.

Однако я не уверен, как отформатировать свой треугольник. В настоящее время он печатается как:

[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
...etc.

Результат, который я хочу:

        [1]
      [1, 1]
    [1, 2, 1]
  [1, 3, 3, 1]
[1, 4, 6, 4, 1]
...etc.

(Это немного не так из-за скобок/запятых, но я просто пытаюсь получить общий формат прямо сейчас.)

Спасибо за любую помощь, которую вы можете предложить!


person Python Newbie    schedule 10.11.2010    source источник


Ответы (5)


h = int(raw_input("Please enter the height of the triangle: "))
for i in mytri(h):
    print " " * (h * 2), i
    h -= 1

Итак, здесь вы печатаете 2 пробела для каждого уровня пирамиды. Отступ первой строки равен удвоенному количеству пробелов по высоте. Спускаясь на один уровень, вы уменьшаете отступ на 2.

person cababunga    schedule 10.11.2010
comment
Предназначено ли это для замены i в mytri(int(raw_input(Пожалуйста, введите высоту треугольника: ))): print i Или предназначено для размещения в другом месте программы? - person Python Newbie; 10.11.2010
comment
Это предполагает замену первых двух строк функции mymenu. - person cababunga; 10.11.2010

Вот пара советов. Пытаться:

' ' * someNumber

для интервала. Если вам не нужны скобки списка, вы можете перебрать строку:

for el in i:
  # Write el as you want

или используйте join.

Вы также можете найти enumerate полезным для получения индексов (например, для интервалов).

person Matthew Flaschen    schedule 10.11.2010

После того, как у вас есть строки, вы, вероятно, сделаете последнюю строку самой длинной.

Поскольку вы просто распечатываете их, вы можете затем взять l = len(str(rows[-1])), а затем объединить это с str(rows[i]).center(l) для каждой строки.

EDIT: Не знал, что мы должны дать все ответы на домашнее задание... Если да:

def mytri(myrange):
    rows = list()
    lr = None # Last row

    for i in xrange(myrange+1):
        try:
            lr = [1] + [lr[i] + lr[i+1] for i in range(len(lr) - 1)] + [1]
        except TypeError:
            lr = [1]
        #rows.append(str(lr))
        rows.append(' '.join(str(v) for v in lr))
    return rows

rows = mytri(10)
l = len(rows[-1])
print '\n'.join(v.center(l) for v in rows)

Будет ли вывод

                 1                 
                1 1                
               1 2 1               
              1 3 3 1              
             1 4 6 4 1             
           1 5 10 10 5 1           
          1 6 15 20 15 6 1         
        1 7 21 35 35 21 7 1        
       1 8 28 56 70 56 28 8 1      
    1 9 36 84 126 126 84 36 9 1    
1 10 45 120 210 252 210 120 45 10 1
person Danosaure    schedule 10.11.2010

Вместо того, чтобы регенерировать предыдущие строки на каждой итерации, вы можете возвращать каждую строку по мере ее создания:

def mytri(height):
  start = [1]
  for _ in xrange(height):  # "_" for an unused variable
    yield start  # loop written "backwards" for simplicity,
    # though this does generate one unused row
    next_row = [1]
    for a, b in zip(start, start[1:]):  # slicing creates a new list, not a
      next_row.append(a + b)            # concern for this problem, but in
    next_row.append(1)                  # others you could use itertools.islice
    start = next_row                    # to avoid that

Теперь перечислите высоту в обратном порядке вместе с каждой строкой:

height = int(raw_input("Height: "))
for n, row in zip(xrange(height - 1, -1, -1), mytri(height)):
  print "   " * n, " ".join("%5d" % x for x in row)

Это быстро не выровняется с очень большим количеством строк, но это должно направить вас в правильном направлении.

person Community    schedule 10.11.2010

Вам нужно дополнить все числа, чтобы они были одинаковой ширины
Вам также нужно добавить отступ слева

def mymenu():
    res = mytri(int(raw_input("Please enter the height of the triangle: ")))
    width = len(str(res[-1][len(res[-1])/2]))
    for i, row in enumerate(res):
        print " "*(width*(len(res)-i)/2)+" ".join(str(x).rjust(width) for x in row)
    print '\n'
    choicevar = raw_input("Would you like to create another triangle? (y/n): ")
    if choicevar == "y":
        mymenu()
    else:
        print "Goodbye."

выход:

Please enter the height of the triangle: 10
                1 
              1   1 
             1   2   1 
           1   3   3   1 
          1   4   6   4   1 
        1   5   10  10  5   1 
       1   6   15  20  15  6   1 
     1   7   21  35  35  21  7   1 
    1   8   28  56  70  56  28  8   1 
  1   9   36  84 126 126  84  36  9   1 
person John La Rooy    schedule 10.11.2010