views:

285

answers:

6

This is similar to http://stackoverflow.com/questions/1523660/how-to-print-a-list-in-python-nicely, but I would like to print the list even more nicely -- without the brackets and apostrophes and commas, and even better in columns.

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

evenNicerPrint(foolist)

Desired result:

exiv2-devel       msvcrt        
mingw-libs        gdal-grass    
tcltk-demos       iconv         
fcgi              qgis-devel    
netcdf            qgis1.1       
pdcurses-devel    php_mapscript

thanks!

+5  A: 

Simple:

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

split = len(l)/2
l1 = l[0:split]
l2 = l[split:]
for key, value in zip(l1,l2):
    print '%-20s %s' % (key, value)
Aaron Digulla
that will not produce the output (data is in column major order).
roe
Thanks, fixed :)
Aaron Digulla
I accept this as the answer because I got it to work reliably in the shortest amount of time -- and I can understand it. While it would be better to have dynamic multicolumn reporting as some of the other answers, I couldn't get them to work reliably (likely because I haven't been able to follow the logic in them) -- sometimes items are dropped from the list as it grows/shrinks, or they no longer line up in columns. Thanks Aaron!
matt wilkie
+2  A: 

If the data is in the format you have provided, it is a little more work


>>> d = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
...     'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
...     'qgis1.1', 'php_mapscript']
>>> print "\n".join("%-20s %s"%(d[i],d[i+len(d)/2]) for i in range(len(d)/2))
exiv2-devel          msvcrt
mingw-libs           gdal-grass
tcltk-demos          iconv
fcgi                 qgis-devel
netcdf               qgis1.1
pdcurses-devel       php_mapscript
gnibbler
upvote for one-liner solution
mizipzor
+1  A: 

See formatting-a-list-of-text-into-columns,

A general solution, handles any number of columns and odd lists. Tab characters separate columns, using generator expressions to save space.

def fmtcols(mylist, cols):
    lines = ("\t".join(mylist[i:i+cols]) for i in xrange(0,len(mylist),cols))
    return '\n'.join(lines)
gimel
A: 

The way Aaron has done it can work with more than two colums


>>> l = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
...     'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
...     'qgis1.1', 'php_mapscript']
>>> cols = 4
>>> split=[l[i:i+len(l)/cols] for i in range(0,len(l),len(l)/cols)]
>>> for row in zip(*split):
...  print "".join(str.ljust(i,20) for i in row)
... 
exiv2-devel         fcgi                msvcrt              qgis-devel          
mingw-libs          netcdf              gdal-grass          qgis1.1             
tcltk-demos         pdcurses-devel      iconv               php_mapscript       
gnibbler
if the length of l is not a multiple of cols, you can pad it by adding some empty strings to the end
gnibbler
A: 
from itertools import izip_longest, islice
L = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript']

def columnize(sequence, columns=2):
    size, remainder = divmod(len(sequence), columns)
    if remainder: 
        size += 1
    slices = [islice(sequence, pos, pos + size) 
              for pos in xrange(0, len(sequence), size)]
    return izip_longest(fillvalue='', *slices)

for values in columnize(L):
    print ' '.join(value.ljust(20) for value in values)
nosklo
A: 

I had a problem similar to Matt's, though it has been solved with the code provided by nosklo. Unfortunately I do not actually understand how this code works.

In particular I have struggled to figure out the meaning and logic of the values 'pos' and 'pos + size' in the following bit of nosklo's solution:

slices = [islice(sequence, pos, pos + size) 
          for pos in xrange(0, len(sequence), size)]
return izip_longest(fillvalue='', *slices)

I've looked up the islice iterator on the official python website and realise that it takes the following arguments (seq, [start], stop, [,step]), so I understand that the 'sequence' argument in nosklo's code refers to matt's list, but I am lost as to what 'pos' is. In my effot to find out I added in a 'print pos' command to see what value pos took and I generally got a number that was half of the number of items in the array - but I can't figure out why this is so and how this value gets used. Also, the '*slices' argument in izip_longest(fillvalue='', *slices) doesn't make any sense to me either. Can anyone enlighten me?

Paul