2

I have a list of namedtuples and want to be able to print the elements of a tuple in a way so that it would be easy to easy to read. Each row of the list contains about 50+ namedtuple elements.

namedtuple = ('apple', 'box', 'cat', 'dog', 'phone', 'elephant', 'horse', 'goose', 'frog')

Desired Output:

apple   dog        goose 
box     elephant   horse
cat     frog
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • what does "namedtuple" refer to here? it's a specific term in Python which does not seem to be used in your code. – Erik Kaplun Apr 16 '14 at 19:01
  • possible duplicate of [Python: Printing Lists as Tabular Data](http://stackoverflow.com/questions/9535954/python-printing-lists-as-tabular-data) – wim Apr 16 '14 at 19:02
  • What you have is a tuple of strings - [namedtuples](https://docs.python.org/2/library/collections.html#collections.namedtuple) are a very specific datatype in Python which is not used here. – Jakub Wasilewski Apr 16 '14 at 19:15

3 Answers3

1

Step 1: sort the tuple.

sortedtuple = sorted(namedtuple)

Step 2: divide the tuple into columns.

num_rows = (len(sortedtuple) + num_columns-1) // num_columns
columns = [sortedtuple[i*num_rows:(i+1)*num_rows] for i in range(num_columns)]

Step 3: extend the last column with blanks so it's the same size as the others.

columns[-1] = columns[-1] + ['']*(len(columns[0])-len(columns[-1]))

Step 4: iterate over a zipped list of columns and print them.

width = max(len(word) for word in sortedtuple)
for row in zip(*columns):
    print '  '.join(word + ' '*(width- len(word)) for word in row)
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • The number of rows you have here is incorrect - should be `len(...) + num_columns - 1` to round the division result up correctly. Otherwise with 3 values in 3 columns you get 2 rows. Also, there is no need to allocate additional lists for the columns themselves. – Jakub Wasilewski Apr 16 '14 at 19:20
  • @JakubWasilewski, thanks for the correction. It was just a typo. – Mark Ransom Apr 16 '14 at 19:22
0

For printing ASCII tables with Python, I used PrettyTable some time ago with success: https://code.google.com/p/prettytable/

As to the sorting, just use the built in sorted() function; then take equal sized slices from the tuple and add them to the PrettyTable object.

Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
0

A simple way of doing it (Python 3 - you did not specify 2.x or 3.x), where columns is the desired number of columns:

def print_in_columns(values, columns):
  values = sorted(values) # for alphabetical order
  column_width = max(len(s) for s in values) + 2 # you could pick this explicitly
  rows = (len(values) + columns - 1) // columns # rounding up
  format = "{:" + str(column_width) + "}"
  for row in range(rows):
    for value in values[row::rows]:
      print(format.format(value), end="")
    print()

Each row you print is simply a slice of the original tuple, with the right step value.

Jakub Wasilewski
  • 2,916
  • 22
  • 27