Python Output Align by Column
I have used several ways in the past to have very simple column headers and subsequent output lines line up. Of course everything can be static but I like to have column headers adjust their size based on some of the data.
For example if I have column headers in an array like this:
header = ['File Name','File Size']
I want to use this array to print the header line but before printing it I want to adjust the column width for 'File Name' to the longest file name that is in the list yet to be processed. The following example is one way of doing it.
I played with other options also(see update 01.24.15 below).
Honestly I think the main reason for doing it dynamically is I like to print the headers and data with minimal lines of code.
#!/usr/bin/env python import os,glob,sys FORMAT = [('File Name',10),('Size',12)] ## In a real use case this function will probably do a lot more ## for example MB to GB conversions etc. ## But important here is where I make the adjustment to the main array ## to stretch the 'File Name' field. def makeEntry(fileN,fileS): global FORMAT entry = [] entry = [fileN, fileS] if len(fileN) > FORMAT[0][1]: n = dict(FORMAT) # tuples are immutable so have to change to something writeable n['File Name'] = len(fileN) + 2 # expanding field width FORMAT = n.items() # overwrite original return entry os.chdir('/DATA/') video_files = [] for files in ('*.m4v', '*.mp4', '*.ts','*.dvr-ms','*.avi','*.mkv'): video_files.extend(glob.glob(files)) ## Loop through files and build an array fArr = [] for fileN in video_files: fArr.append(makeEntry(fileN, os.path.getsize(fileN))) ## Print header for item in FORMAT: print "{header:{width}}".format (header=item[0], width=item[1]), print ## Print entries for entry in fArr: #print ("%-" + str(FORMAT[0][1]) + "s %-" + str(FORMAT[1][1]) + "s") % (entry[0], entry[1]) # old style print "{f0:{w0}} {f1:{w1}}".format ( f0=entry[0], w0=FORMAT[0][1], f1=entry[1], w1=FORMAT[1][1] ) # new style
Update 01.24.15
Above example is fine except I did not like the way I updated the tuple. Below example use a dict for the header.
#!/usr/bin/env python import os,glob,sys FORMAT = {'File Name':10,'Size':12} def makeEntry(fileN,fileS): global FORMAT entry = [] entry = [fileN, fileS] if len(fileN) > FORMAT['File Name']: FORMAT['File Name'] = len(fileN) + 2 # expanding field width return entry os.chdir('/DATA/') video_files = [] for files in ('*.m4v', '*.mp4', '*.ts','*.dvr-ms','*.avi','*.mkv'): video_files.extend(glob.glob(files)) fArr = [] for fileN in video_files: fArr.append(makeEntry(fileN, os.path.getsize(fileN))) ## Print header. print "{header:{width}}".format (header='File Name', width=FORMAT['File Name']), print "{header:{width}}".format (header='Size', width=FORMAT['Size']) print for entry in fArr: print "{f0:{w0}} {f1:{w1}}".format ( f0=entry[0], w0=FORMAT['File Name'], f1=entry[1], w1=FORMAT['Size'] )