0

I need my func to print out the following:

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

all items are aligned to the right

and I have solution but it's kinda workaround, could you please help me to correct my solution?

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

def printData(lst):
  colWidths = [0] * len(tableData)

  for a in range(len(tableData)):
    colWidths[a] = len(max(tableData[a], key=len))

  for i in range(len(lst[0])):
    output = ''
    for j in range(len(lst)):
      output += (str(lst[j][i])).rjust(colWidths[0])
    print(output)


print(printData(tableData))

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

2 Answers2

3

You can use the format specification mini language together with str.format

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

for tup in zip(*tableData):
    print("{:>9} {:>9} {:>9}".format(*tup))

prints

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

EDIT:

You can generate these strings dynamically, if you don't know what size you want the columns when you write the code

from itertools import chain

def gen_format_str(widths):
    return ' '.join(["{{:>{}}}".format(width) for width in widths])

def n_of_width(n, width):
    return gen_format_str([width] * n)

def all_widest(list_of_lists):
    return n_of_width(len(list_of_lists), max(map(len, chain.from_iterable(list_of_lists))))

format_str = all_widest(tableData)

for tup in zip(*tableData):
    print(format_str.format(*tup))

format_str is '{:>8} {:>8} {:>8}', because the longest word, "cherries" is 8 characters long.

Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
0

Doing this:

for index in range(len(tableData)):

is wrong about 80% of the time. Try it first with for a in mylist or with for index,a in enumerate(mylist). That is usually a simpler approach.

In this case:

>>> tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]
>>> fruits, persons, pets = tableData
>>> for n,fruit in enumerate(fruits):
        print (f"{fruit:>8s} {persons[n]:>8s} {pets[n]:>8s}")
  apples    Alice     dogs
 oranges      Bob     cats
cherries    Carol    moose
  banana    David    goose

But that doesn't handle scaling the column widths to take the least amount of space needed. To include that refinement, compute the column widths and include them in the formatting:

>>> widths = [max(len(x) for x in d) for d in tableData]
>>> for n,fruit in enumerate(fruits):
        print (f"{fruit:>{widths[0]}s} {persons[n]:>{widths[1]}s} {pets[n]:>{widths[2]}s}")

  apples Alice  dogs
 oranges   Bob  cats
cherries Carol moose
  banana David goose
BoarGules
  • 16,440
  • 2
  • 27
  • 44