1

I've been looking into how to print data into columns. I haven't been able to find an elegant way to do this with either a dictionary (keys) or a list (taking keys from dictionary into list).

Ive looked into iterating over each key and printing that, but that doesn't work as you can't use mapping. I've tried using a list and printing each item from the list using string formatting but as you'd imagine I get back each character with a space from each list item, I can't seem to use .join. The closest I have been able to get to what I'd like is the answer from Aaron Digulla here. However this does not print the list items in alphabetical order. I cant believe there is'nt a simple elegant way to do this?

Method from answer discussed above

l = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript']

if len(l) % 2 != 0:
    l.append(" ")

split = len(l)/2
l1 = l[0:split]
l2 = l[split:]
for key, value in zip(l1,l2):
    print "{0:<20s} {1}".format(key, value)
Community
  • 1
  • 1
iNoob
  • 1,271
  • 2
  • 17
  • 41

2 Answers2

2

You can use sort, try:

l = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript']

l.sort()# Alphabetizes l

if len(l) % 2 != 0:
    l.append(" ")

split = len(l)/2
l1 = l[0:split]
l2 = l[split:]
for key, value in zip(l1,l2):
    print "{0:<20s} {1}".format(key, value)
  • arr it seems this does work, haha I tried this previously but had left my previous attempt (setting the l1 and l2 lists) so it didnt appear to do the job. So as you just mentioned it I thought I must have missed a trick. Thanks Martin – iNoob Nov 05 '15 at 22:00
  • as this is using zip to create a dictionary its safe to assume you cant have more than 2 columns? after all you cant zip more than 2 columns into a dict can you? hmm unless you maybe nest them? – iNoob Nov 05 '15 at 22:05
  • `zip` isn't creating a dictionary, it's just creating a series of tuples that you happen to be unpacking and calling `key` and `value`. Something like `for x, y, z in zip(l1, l2, l3)` or even `for items in zip(l1, l2... l9)` works fine, though you will need to edit the string output as well. – zehnpaard Nov 05 '15 at 22:29
0

Here is a somewhat more generic version which lets you specify the number of columns:

def print_in_columns(iterable, cols=2, col_width=20, key=None, reverse=False):
    # get items in output order
    items = sorted(iterable, key=key, reverse=reverse)
    # calculate number of output rows, and pad as needed
    rows = (len(items) + cols - 1) // cols
    pad  = rows * cols - len(items)
    items.extend("" for _ in range(pad))
    # prepare output template
    item_fmt = "{{:{}s}}".format(col_width)
    row_fmt  = " ".join(item_fmt for _ in range(cols))
    # print by row
    for r in range(rows):
        print(row_fmt.format(*(items[r::rows])))

which used like

files = [
    'exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript'
]

print_in_columns(files, cols=4, col_width=16)

produces

exiv2-devel      iconv            netcdf           qgis-devel
fcgi             mingw-libs       pdcurses-devel   qgis1.1
gdal-grass       msvcrt           php_mapscript    tcltk-demos
Hugh Bothwell
  • 50,702
  • 6
  • 75
  • 95