98

Is there a simple, built-in way to print a 2D Python list as a 2D matrix?

So this:

[["A", "B"], ["C", "D"]]

would become something like

A    B
C    D

I found the pprint module, but it doesn't seem to do what I want.

martineau
  • 119,623
  • 25
  • 170
  • 301
houbysoft
  • 32,532
  • 24
  • 103
  • 156
  • 6
    I would have called that a 3D list. If you are willing to pull it in, `numpy` is pretty good about this sort of thing. – tacaswell Nov 04 '12 at 00:20
  • Actually, `print` has a pretty neat way to do things like this. There is an `end = foo` argument that allows you to customize what you put at the end of a print statement (default is `\n`). See my answer for future reference: https://stackoverflow.com/a/73229153/13600624. – ᴇɴᴅᴇʀᴍᴀɴ Aug 12 '22 at 15:47
  • The simplest solution for this example would be just `for x in your_list: print(x)` – Petr L. Feb 11 '23 at 11:33

12 Answers12

99

To make things interesting, let's try with a bigger matrix:

matrix = [
   ["Ah!",  "We do have some Camembert", "sir"],
   ["It's a bit", "runny", "sir"],
   ["Well,",  "as a matter of fact it's", "very runny, sir"],
   ["I think it's runnier",  "than you",  "like it, sir"]
]

s = [[str(e) for e in row] for row in matrix]
lens = [max(map(len, col)) for col in zip(*s)]
fmt = '\t'.join('{{:{}}}'.format(x) for x in lens)
table = [fmt.format(*row) for row in s]
print '\n'.join(table)

Output:

Ah!                     We do have some Camembert   sir            
It's a bit              runny                       sir            
Well,                   as a matter of fact it's    very runny, sir
I think it's runnier    than you                    like it, sir  

UPD: for multiline cells, something like this should work:

text = [
    ["Ah!",  "We do have\nsome Camembert", "sir"],
    ["It's a bit", "runny", "sir"],
    ["Well,",  "as a matter\nof fact it's", "very runny,\nsir"],
    ["I think it's\nrunnier",  "than you",  "like it,\nsir"]
]

from itertools import chain, izip_longest

matrix = chain.from_iterable(
    izip_longest(
        *(x.splitlines() for x in y), 
        fillvalue='') 
    for y in text)

And then apply the above code.

See also http://pypi.python.org/pypi/texttable

georg
  • 211,518
  • 52
  • 313
  • 390
67

For Python 3 without any third part libs:

matrix = [["A", "B"], ["C", "D"]]

print('\n'.join(['\t'.join([str(cell) for cell in row]) for row in matrix]))

Output

A   B
C   D
Rodrigo López
  • 4,039
  • 1
  • 19
  • 26
57

If you can use Pandas (Python Data Analysis Library) you can pretty-print a 2D matrix by converting it to a DataFrame object:

from pandas import *
x = [["A", "B"], ["C", "D"]]
print DataFrame(x)

   0  1
0  A  B
1  C  D
Alceu Costa
  • 9,733
  • 19
  • 65
  • 83
sten
  • 7,028
  • 9
  • 41
  • 63
  • 9
    While this answer is probably correct and useful, it is preferred if you [include some explanation along with it](http://meta.stackexchange.com/q/114762/159034) to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a change (possibly unrelated) that causes it to stop working and users need to understand how it once worked. – Kevin Brown-Silva Aug 22 '15 at 18:48
  • 3
    This is exactly what I wanted. Thanks. – Arvind Jan 22 '18 at 07:31
40

You can always use numpy:

import numpy as np
A = [['A', 'B'], ['C', 'D']]
print(np.matrix(A))

Output:

[['A' 'B']
 ['C' 'D']]
Sash Sinha
  • 18,743
  • 3
  • 23
  • 40
Souradeep Nanda
  • 3,116
  • 2
  • 30
  • 44
12

Just to provide a simpler alternative to print('\n'.join(\['\t'.join(\[str(cell) for cell in row\]) for row in matrix\])) :

matrix = [["A", "B"], ["C", "D"]]
for row in matrix:
    print(*row)

Explanation *row unpacks row, so print("A", "B") is called when row is ["A", "B"], for example.

Note Both answers will only be formatted nicely if each column has the same width. To change the delimiter, use the sep keyword. For example,

for row in matrix:
    print(*row, sep=', ')

will print

A, B
C, D

instead.

One-liner without a for loop

print(*(' '.join(row) for row in matrix), sep='\n')

' '.join(row) for row in matrix) returns a string for every row, e.g. A B when row is ["A", "B"].

*(' '.join(row) for row in matrix), sep='\n') unpacks the generator returning the sequence 'A B', 'C D', so that print('A B', 'C D', sep='\n') is called for the example matrix given.

Community
  • 1
  • 1
LHeng
  • 531
  • 5
  • 9
9

Without any third party libraries, you could do:

matrix = [["A", "B"], ["C", "D"]]
print(*matrix, sep="\n")

Output:

['A', 'B']
['C', 'D']
Omar
  • 204
  • 2
  • 3
6

A more lightweight approach than pandas is to use the prettytable module

from prettytable import PrettyTable

x = [["A", "B"], ["C", "D"]]

p = PrettyTable()
for row in x:
    p.add_row(row)

print p.get_string(header=False, border=False)

yields:

A B
C D

prettytable has lots of options to format your output in different ways.

See https://code.google.com/p/prettytable/ for more info

Dov Grobgeld
  • 4,783
  • 1
  • 25
  • 36
5

If you're using a Notebook/IPython environment, then sympy can print pleasing matrices using IPython.display:

import numpy as np
from sympy import Matrix, init_printing
init_printing()

print(np.random.random((3,3)))
display(np.random.random((3,3)))
display(Matrix(np.random.random((3,3))))

enter image description here

ZSG
  • 1,329
  • 14
  • 18
3

I would also recommend tabulate, which can optionally print headers too:

from tabulate import tabulate

lst = [['London', 20],['Paris', 30]]
print(tabulate(lst, headers=['City', 'Temperature']))

:

City      Temperature
------  -------------
London             20
Paris              30
Reveille
  • 4,359
  • 3
  • 23
  • 46
1

A simpler way is to do it using the "end" parameter in print(). This works only because in Python (and in many other languages), all letters are the same width.

table = [["A", "BC"], ["DEFG", "HIJ"]]
for row in table:
    for col in row:
        spaces = 5 #adjust as needed
        spaces -= (len(col) - 1) #spaces everything out
        print(col, end = " " * spaces)
    print() #add line break before next row

The "end" function sets what will be printed after the end of the arguments, as the default is \n.

As you can see, I offseted how many spaces there are according to the length of each item in each row.

0

You can update print's end=' ' so that it prints space instead of '\n' in the inner loop and outer loop can have print().

a=[["a","b"],["c","d"]]
for i in a:
  for j in i:
    print(j, end=' ')
  print()

I found this solution from here.

Ynjxsjmh
  • 28,441
  • 6
  • 34
  • 52
Sandeep
  • 106
  • 1
  • 4
-4

See the following code.

# Define an empty list (intended to be used as a matrix)
matrix = [] 
matrix.append([1, 2, 3, 4])
matrix.append([4, 6, 7, 8])
print matrix
# Now just print out the two rows separately
print matrix[0]
print matrix[1]
Community
  • 1
  • 1
jfconroy
  • 13
  • 2
  • try this and see what happens does not sound like an answer. Please review: https://stackoverflow.com/help/how-to-answer – Daniel Jan 13 '18 at 14:48