5

I have this list of lists:

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

that i have to transform into this table:

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

The trick for me, is have the "lines" to be converted into columns (i.e. apples, oranges, cherries, banana under same column)

I have tried different options (A):

for row in tableData:
        output = [row[0].ljust(20)]
            for col in row[1:]:
             output.append(col.rjust(10))
            print(' '.join(output))

option (B):

method 2

for i in tableData:
    print( i[0].ljust(10)+(str(i[1].ljust(15)))+(str(i[2].ljust(15)))+
    (str(i[3].ljust(15))))    

None seems to address the issue.
Thanks in advance for any suggestions.

Community
  • 1
  • 1
AT_1965
  • 99
  • 1
  • 5
  • 11

4 Answers4

8

To transpose the table, use the zip-and-splat trick.

To left-or-right-justify cells, use the format spec language:

>>> for row in zip(*tableData):
...     print '{:<10}{:>7}    {:<10}'.format(*row)
...     
apples      Alice    dogs      
oranges       Bob    cats      
cherries    Carol    moose     
banana      David    goose   
wim
  • 338,267
  • 99
  • 616
  • 750
  • No need for explicit field width on the final entry, since it's left justified and will spill if it exceeds the width anyway. Otherwise, yeah, best answer. – ShadowRanger Sep 06 '16 at 22:51
  • thank you. what exactly do these #'s represent – AT_1965 Sep 06 '16 at 23:24
  • 1
    Did you follow the link? The numbers are the space that is reserved for the content so that left-or-right-justify knows how many spacess have to be added on the left or right side. – Matthias Sep 07 '16 at 04:26
2

One could also play around with pandas.DataFrame:

In [22]: import pandas as pd
In [22]: pd.DataFrame(tableData).T # .T means transpose the dataframe
Out[22]:
          0      1      2
0    apples  Alice   dogs
1   oranges    Bob   cats
2  cherries  Carol  moose
3    banana  David  goose

Remove those annoying numbers by setting columns and indices to blank:

In [27]: l1, l2 = len(tableData), len(tableData[0])

In [28]: pd.DataFrame(tableData, index=['']*l1, columns=['']*l2).T
Out[28]:

    apples  Alice   dogs
   oranges    Bob   cats
  cherries  Carol  moose
    banana  David  goose
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
  • 1
    Not downvoting, but I think whipping out `pandas` for a simple problem might be overdoing it, just a bit. :-) – ShadowRanger Sep 06 '16 at 22:57
  • @ShadowRanger I did considered that, but on a second thought I think it's a tool worth considering by the questioner (if not now, in the long run) :) – Moses Koledoye Sep 06 '16 at 23:01
1

The easiest way to "flip" the nested list is to use zip:

for fruit, name, animal in zip(*tableData):
    print(fruit.ljust(10), name.ljust(10), animal.ljust(10))

This prints:

apples     Alice      dogs
oranges    Bob        cats
cherries   Carol      moose
banana     David      goose
L3viathan
  • 26,748
  • 2
  • 58
  • 81
0

There is already a builtin function for this: zip.

zip(* [['apples', 'oranges', 'cherries', 'banana'],
       ['Alice', 'Bob', 'Carol', 'David'],
       ['dogs', 'cats', 'moose', 'goose']])
zvone
  • 18,045
  • 3
  • 49
  • 77