Printing Pascal’s triangle for n number of rows in Python I have written a program that takes a number n and prints Pascal's triangle having n number of rows. 

Here is my code -

n = int(input("Enter number of rows: "))
a = []

for i in range(n):
    a.append([])
    a[i].append(1)

    for j in range(1, i):
        a[i].append(a[i - 1][j - 1] + a[i - 1][j])
    if (n != 0):
        a[i].append(1)

for i in range(n):
    print("   " * (n - i), end = " ", sep = " ")

    for j in range(0, i + 1):
        print('{0:5}'.format(a[i][j]), end = " ", sep = " ")
    print()


Here are some example outputs -

Enter number of rows: 3
              1 
           1     1 
        1     2     1 




Enter number of rows: 6
                       1 
                    1     1 
                 1     2     1 
              1     3     3     1 
           1     4     6     4     1 
        1     5    10    10     5     1 




Enter number of rows: 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 


Therefore, I would like to know whether I could make this program shorter and more efficient.

Any help would be highly appreciated.
One issue with your approach is your memory usage is \$O(n^2)\$.  You are building up the entire Pascal's Triangle, and subsequently printing it.  If you simply want to print Pascal's Triangle, you don't need to keep the entire triangle in memory.  You can simply generate and print it row by row.  Since you generate the next row from only the previous row, the memory requirement is simply two rows, which is \$O(n)\$.

&gt;&gt;&gt; row = [1]
&gt;&gt;&gt; for _ in range(5):
...    row = [1] + [x + y for x, y in zip(row[:-1], row[1:])] + [1]
...    print(row)
... 
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
&gt;&gt;&gt; 


Demystifying [1] + [x + y for x, y in zip(row[:-1], row[1:])] + [1]:

row[:-1] is all the values in row, except the last one.  For example, if row is [1, 3, 3, 1], then row[:-1] is [1, 3, 3].  Similarly, row[1:] is all the values of row except the first, so [3, 3, 1].  zip() takes the first value of each of the lists, and returns those as the tuple (1, 3), which get assigned to x and y respectively, which get added together to get 4.  Then, zip() emits the next pair of values, (3, 3) which results in 6, and then the final pair (3, 1) results in 4, producing the list [4, 6, 4].  The [1] + ... + [1] adds the bookends, which results in the next row of the triangle: [1, 4, 6, 4, 1].

Instead of needing to keep track of the last row, and feed that back to generate the next row, we can package that up into a generator function, which can prime the loop and do the feedback itself:

&gt;&gt;&gt; def pascals_triangle(n):
...     row = [1]
...     yield row
...     for _ in range(n):
...         row = [1] + [x + y for x, y in zip(row[:-1], row[1:])] + [1]
...         yield row
... 
&gt;&gt;&gt; for row in pascals_triangle(5):
...     print(row)
... 
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
&gt;&gt;&gt; 


Format the resulting rows as desired.

&gt;&gt;&gt; for i, row in enumerate(pascals_triangle(5)):
...     print(("   "*(5-i) + "{:6}"*(i+1)).format(*row))
... 
                    1
                 1     1
              1     2     1
           1     3     3     1
        1     4     6     4     1
     1     5    10    10     5     1
&gt;&gt;&gt;