2

I'm trying to display a nested list as a column. So the data that I'm working with is:

tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']]

which I want to display as

  apples Alice  dogs
 oranges   Bob  cats
cherries Carol moose
  banana David goose

so that the entries are right aligned. I've had a look at Create nice column output in python but I'm not able to implement it for a similar outcome. The code that I have so far is:

tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']]

total_len= [[] for x in range(len(tableData))]
longest_string = []

for y1 in range(0, len(tableData)):
    for y2 in range(0, len(tableData[y1])):       
        total_len[y1].append(len(tableData[y1][y2]))

for y1 in range(0, len(total_len)):    
    longest_string.append(max(total_len[y1]))

for y1 in range(len(tableData)):
    for y2 in range(len(tableData[y1])):
        print("".join(tableData[y1][y2].rjust(longest_string[y1])))
Community
  • 1
  • 1
Lukasz
  • 2,476
  • 10
  • 41
  • 51

3 Answers3

3

zip() and the solution from the linked thread:

>>> for row in zip(*tableData):
...     print("{: >10} {: >10} {: >10}".format(*row))
... 
    apples      Alice       dogs
   oranges        Bob       cats
  cherries      Carol      moose
    banana      David      goose

Though I really like the "pandas" dataframe based solution more.

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
1

I don't know do you have a pandas but if you do it's pretty easy to that. You could create dataframe and then use to_string method:

import pandas as pd
tableData = [['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']]
df = pd.DataFrame(tableData).T

In [224]: df
Out[224]: 
          0      1      2
0    apples  Alice   dogs
1   oranges    Bob   cats
2  cherries  Carol  moose
3    banana  David  goose

result = df.to_string(index=False, header=False)

In [228]: print(result)
   apples  Alice   dogs
  oranges    Bob   cats
 cherries  Carol  moose
   banana  David  goose
Anton Protopopov
  • 30,354
  • 12
  • 88
  • 93
1

Similar formatting without 3rd party pandas:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

# Find the max length of the word in each row
lens = [max(len(col) for col in row) for row in tableData]

# zip(*list) transposes a list...rows become columns
for row in zip(*tableData):
    # Pass the column widths dynamically.
    print('{:>{lens[0]}} {:>{lens[1]}} {:>{lens[2]}}'.format(*row,lens=lens))

Output:

  apples Alice  dogs
 oranges   Bob  cats
cherries Carol moose
  banana David goose

EDIT

Here's a version that can dynamically display any number of rows and columns:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

# Find the max length of the word in each row
lens = [max(len(col) for col in row) for row in tableData]

# build a format string with an entry for each column
rowfmt = '{:>{}} ' * len(tableData)

# zip(*list) transposes a list...rows become columns
for row in zip(*tableData):
    # Pass the values and column widths dynamically.
    # The zip pairs up each datum with its column width, but in tuples.
    # For example, [data1,data2],[width1,width2] -> [(data1,width1),(data2,width2)]
    # itertools.chain flattens the list of tuples.
    # For example, above becomes [data1,width1,data2,width2]
    print(rowfmt.format(*itertools.chain(*zip(row,lens))))
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • I figured that your in your for loop the print statement has 3 entries of the form {:>{lens[i]}} because there are 3 sublists in table data which is specific to this example. Would it be possible to have some sort of function that can take any list containing any number of sublists and display it in the same fashion? – Lukasz Dec 30 '15 at 21:41
  • 1
    @user49231, yes with some more work and more complicated code. I'll add a more flexible example. – Mark Tolonen Dec 30 '15 at 21:59