# python 2 or 3
# Author: Gribouillis for the python forum at www.daniweb.com
# licence: public domain
# use this code freely.
# 03 Mar '15: version 0.2.1, bug fix for empty list and added file, flush args.
# 21 Dec '13: version 0.1, bug fix and added re-calculation of ncols.
from __future__ import print_function
from distutils.version import StrictVersion # pep 386
import prettytable as ptt # pip install prettytable
import sys
assert StrictVersion(ptt.__version__) >= StrictVersion('0.7') # for PrettyTable.vrules property

__version__ = '0.2.1'

def example_list():
    """Return sorted list of python module names"""
    import pkgutil
    L = list(sys.builtin_module_names)
    L.extend(t[1] for t in pkgutil.iter_modules())
    return sorted(L)

def print_multicolumn(alist, ncols, vertically=True, file=None, flush=False):
    """Print a list of strings in several columns
    
    alist: the list to print
    ncols: the desired number of columns in output
    vertically: whether the list items must be enumerated column by
                column or row by row, defaults to True.
    file: a file-like object (stream), defaults to sys.stdout.
    flush: whether to forcibly flush the stream, defaults to False.
    """
    L = alist
    if not L:
        if flush(): file.flush()
        return
    # incompressible number of rows without adding columns.
    nrows = - ((-len(L)) // ncols)
    # the number of columns may be reducible for that many rows.
    ncols = - ((-len(L)) // nrows)
    t = ptt.PrettyTable([str(x) for x in range(ncols)])
    t.header = False
    t.align = 'l'
    t.hrules = ptt.NONE
    t.vrules = ptt.NONE
    r = nrows if vertically else ncols
    chunks = [L[i:i+r] for i in range(0, len(L), r)]
    chunks[-1].extend('' for i in range(r - len(chunks[-1])))
    if vertically:
        chunks = zip(*chunks)
    for c in chunks:
        t.add_row(c)
    if file is None: file = sys.stdout
    print(t, file=file)
    if flush: file.flush()
    
if __name__ == '__main__':
    L = example_list()
    print_multicolumn(L, 4, vertically = True)
	
""" my output -->
  CDROM                 aifc              heapq                   readline       
  CommandNotFound       antigravity       hmac                    reprlib        
  DLFCN                 apt               html                    resource       
  DistUpgrade           apt_clone         http                    rlcompleter    
  IN                    apt_inst          icu                     runpy          
  LanguageSelector      apt_pkg           idlelib                 sandbox    
  ...
"""
1
Contributor
1
Reply
272
Views
3 Years
Discussion Span
Last Post by Gribouillis
1

This can actually be used to mimick the action of the ls command with colorful output. The following code lists the user's home directory with colors:

from termcolor import colored # pip install termcolor
import sys
if sys.platform == 'win32':
    from colorama import init # pip install colorama
    init()
import os
import stat

def color_code(filename):
    try:
        mode = os.lstat(filename).st_mode
    except OSError:
        return
    if stat.S_ISDIR(mode):
        return 'blue'
    elif stat.S_ISLNK(mode):
        return 'cyan'
    elif stat.S_ISFIFO(mode) or stat.S_ISBLK(mode):
        return 'yellow'
    elif mode & (stat.S_IXUSR):
        return 'green'
    elif filename.endswith((".tar", ".zip", ".deb", ".rpm", ".gz")):
        return 'red'
    elif filename.endswith((".jpg", ".gif", ".png", ".tiff", ".mp3", ".ogg", ".wav")):
        return 'magenta'

def listdir_color(directory):
    L = sorted(os.listdir(directory), key = lambda s: s.lower())
    for i, name in enumerate(L):
        fn = os.path.join(directory, name)
        col = color_code(fn)
        if col is not None:
            L[i] = colored(name, col)
    return L

if __name__ == '__main__':
    L = listdir_color(os.path.expanduser('~'))
    print_multicolumn(L, 4)

It even works in the ipython notebook !

Also notice that (partial) pure python implementations of ls already exist. See the pycoreutils package :)

Edited by Gribouillis

Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.