This is similar to 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 b
this one prints list in separate columns (order is preserved)
from itertools import zip_longest
def ls(items, n_cols=2, pad=30):
if len(items) == 0:
return
total = len(items)
chunk_size = total // n_cols
if chunk_size * n_cols < total:
chunk_size += 1
start = range(0, total, chunk_size)
end = range(chunk_size, total + chunk_size, chunk_size)
groups = (items[s:e] for s, e in zip(start, end))
for group in zip_longest(*groups, fillvalue=''):
template = (' ').join(['%%-%ds' % pad] * len(group))
print(template % group)
usage:
ls([1, 2, 3, 4, 5, 6, 7], n_cols=3, pad=10)
output:
1 4 7
2 5
3 6
note that there may be missing columns if there is not enough number of items, because columns are filled first.
ls([1, 2, 3, 4, 5], n_cols=4)
output:
1 3 5
2 4
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)
Inspired by gimel's answer, above.
import math
def list_columns(obj, cols=4, columnwise=True, gap=4):
"""
Print the given list in evenly-spaced columns.
Parameters
----------
obj : list
The list to be printed.
cols : int
The number of columns in which the list should be printed.
columnwise : bool, default=True
If True, the items in the list will be printed column-wise.
If False the items in the list will be printed row-wise.
gap : int
The number of spaces that should separate the longest column
item/s from the next column. This is the effective spacing
between columns based on the maximum len() of the list items.
"""
sobj = [str(item) for item in obj]
if cols > len(sobj): cols = len(sobj)
max_len = max([len(item) for item in sobj])
if columnwise: cols = int(math.ceil(float(len(sobj)) / float(cols)))
plist = [sobj[i: i+cols] for i in range(0, len(sobj), cols)]
if columnwise:
if not len(plist[-1]) == cols:
plist[-1].extend(['']*(len(sobj) - len(plist[-1])))
plist = zip(*plist)
printer = '\n'.join([
''.join([c.ljust(max_len + gap) for c in p])
for p in plist])
print printer
Results (the second one satisfies your request):
>>> list_columns(foolist)
exiv2-devel fcgi msvcrt qgis-devel
mingw-libs netcdf gdal-grass qgis1.1
tcltk-demos pdcurses-devel iconv php_mapscript
>>> list_columns(foolist, cols=2)
exiv2-devel msvcrt
mingw-libs gdal-grass
tcltk-demos iconv
fcgi qgis-devel
netcdf qgis1.1
pdcurses-devel php_mapscript
>>> list_columns(foolist, columnwise=False)
exiv2-devel mingw-libs tcltk-demos fcgi
netcdf pdcurses-devel msvcrt gdal-grass
iconv qgis-devel qgis1.1 php_mapscript
>>> list_columns(foolist, gap=1)
exiv2-devel fcgi msvcrt qgis-devel
mingw-libs netcdf gdal-grass qgis1.1
tcltk-demos pdcurses-devel iconv php_mapscript
Here is the short and simple method:
def printList1(list, col, STR_FMT='{}', gap=1):
list = [STR_FMT.format(x).lstrip() for x in list]
FMT2 = '%%%ds%%s' % (max(len(x) for x in list)+gap)
print(''.join([FMT2 % (v, "" if (i+1) % col else "\n") for i, v in enumerate(list)]))
Then here is the better method which can turn off the constant width across the entire list instead optimizing it across the columns, restrict the number of columns to fit the max characters per line or find the optimal number of columns to fit the max characters per line, then force left or right justify, and can still can take the optional format string, and gap width between each column.
def printList2(list, col=None, gap=2, uniform=True, ljust=True, STR_FMT="{}", MAX_CHARS=120, end='\n'):
list = [STR_FMT.format(x).strip() for x in list]
Lmax, valid, valid_prev, cp, c = [MAX_CHARS+1], None, None, 1, max(col,1) if col else 1
LoL_prev, Lmax_prev = [], []
while True:
LoL = [list[i::c] for i in range(c)]
Lmax = [max(len(x)+gap for x in L) for L in LoL] # Find max width of each column with gap width
if uniform: # Set each max column width to max across entire set.
Lmax = [max(Lmax) for m in Lmax]
valid_prev, valid = valid, sum(Lmax) <= MAX_CHARS
if (col and (valid or (c == 1))) or not MAX_CHARS: # If column and valid strlen or MAX_CHARS is empty
break
elif valid_prev and not valid_prev == valid: # If valid_prev exist
c = cp if valid_prev and not valid else c
LoL, Lmax = (LoL_prev, Lmax_prev) if valid_prev else (LoL, Lmax)
break
LoL_prev, Lmax_prev = LoL, Lmax
cp, c = c, (c + (+1 if valid else -1))
ljust = '-' if ljust else ''
FMT = ["%%%s%ds%s" % (ljust, max(Lmax) if uniform else m, end if i+1 == c else '') for i, m in enumerate(Lmax)]
outStr = ''.join([''.join([f % v for v, f in zip(L, FMT)]) for L in zip(*LoL)])
remStr = ''.join([f % v for v, f in zip(list[c * (len(list) // c):], FMT)])
print(outStr+(remStr+end if remStr else remStr), end='')
Testing w/ outputs:
>>> foolist = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf',
'pdcurses-devel', 'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel',
'qgis1.1', 'php_mapscript']
>>> printList2(foolist)
exiv2-devel mingw-libs tcltk-demos fcgi netcdf pdcurses-devel msvcrt
gdal-grass iconv qgis-devel qgis1.1 php_mapscript
>>> printList2(foolist, MAX_CHARS=48, uniform=False, gap=3)
exiv2-devel mingw-libs tcltk-demos
fcgi netcdf pdcurses-devel
msvcrt gdal-grass iconv
qgis-devel qgis1.1 php_mapscript
>>> printList2(foolist, col=2, MAX_CHARS=48, uniform=False, gap=3)
exiv2-devel mingw-libs
tcltk-demos fcgi
netcdf pdcurses-devel
msvcrt gdal-grass
iconv qgis-devel
qgis1.1 php_mapscript
>>> printList2(foolist, col=2, MAX_CHARS=48, uniform=False, ljust=False, gap=2)
exiv2-devel mingw-libs
tcltk-demos fcgi
netcdf pdcurses-devel
msvcrt gdal-grass
iconv qgis-devel
qgis1.1 php_mapscript
>>> printList2(foolist, col=10, MAX_CHARS=48, uniform=True, ljust=False, gap=2)
exiv2-devel mingw-libs tcltk-demos
fcgi netcdf pdcurses-devel
msvcrt gdal-grass iconv
qgis-devel qgis1.1 php_mapscript
>>> from math import pi
>>> FloatList = [pi**(i+1) for i in range(32)]
>>> printList2(FloatList, STR_FMT="{:.5g},", col=7, ljust=False)
3.1416, 9.8696, 31.006, 97.409, 306.02, 961.39, 3020.3,
9488.5, 29809, 93648, 2.942e+05, 9.2427e+05, 2.9037e+06, 9.1222e+06,
2.8658e+07, 9.0032e+07, 2.8284e+08, 8.8858e+08, 2.7916e+09, 8.77e+09, 2.7552e+10,
8.6556e+10, 2.7192e+11, 8.5427e+11, 2.6838e+12, 8.4313e+12, 2.6488e+13, 8.3214e+13,
2.6142e+14, 8.2129e+14, 2.5802e+15, 8.1058e+15,