Hey guys,

This is a quick formatting question that I'm having trouble with. I'm trying to create columns of numbers, but I want the columns to only be as large as the largest number in that column. I was trying to use format() width, but that is creating a width between the numbers so the columns don't line up. What I want is something that looks like this (where each of the numbers are a different variable):

CARD  1   5   3   1
CARD 10  23   3  23
CARD  1 122   3 233

Hopefully that makes sense. This problem seems like an easy fix but I can't figure it out and its really bothering me!

Thanks in advance.

Edited 5 Years Ago by fatalaccidents: n/a

You would first have to store the rows so you can find the largest number in each column. Post the code for that and we would then have enough info to be able to help with the final formatting.

Hey, I actually already have that part. Here is what I had so far (as far as getting the largest a number would take up in a row).

76 mw_facets = 1 + int(len(str(num_facets)))
 77 max_tot = 1 + max(len(item) for item in Cells)
 78 max_mat = 1 + max(len(item) for item in Mats)
 79 max_node = 1 + int(len(str(num_nodes)))
 80 max_sp_node = 1 + int(len(str(Nodes[0])))
 81 
 82 padding = ' '
 83 num_facets = int(num_facets)
 84 
 85 f2.write("MESH3D\n")
 86 for i in range(0,num_facets):
 87    E_cnt =  '{0}{p:{mw_facets}}{count}'.format('E4T', p=padding, mw_facets=mw_facets, count=count)
 88    C_cnt = '{p:{r}}{Cell1}{p:{r}}{Cell2}{p:{r}}{Cell3}{p:{r}}{Cell4}{p:{r}}'.format(p=padding, r=max_tot,
 89             Cell1 = Cells[i][0], Cell2 = Cells[i][1], Cell3 = Cells[i][2], Cell4 = Cells[i][3])
 90    M_cnt = '{p:{r}}{Mat}'.format(p=padding, r=max_mat, Mat=Mats[i])
 91    TDM_line = E_cnt + C_cnt + M_cnt
 92    f2.write(TDM_line+'\n')
 93    count += 1

I'm really new to python so any simple suggestions to make my code less ... ugly would also be appreciated. The problem with this code right now is that it takes that maximum space a number will take up and puts that amount between rows. I want the numbers to line up and at least have one space (when the number is the largest) between them, but always the same amount of space between them. I hope I'm being clear, and if I'm not just let me know how I can explain better. Thanks for the reply!

You can compute the column widths and then generate a template for the format() method:

cells = [
    [ 1, 5, 3, 1],
    [ 10, 23, 3, 23 ],
    [ 1, 122, 3, 233]
]

scells = [[str(x) for x in line] for line in cells]
columns = zip(*scells)
padding = 2
width = [ max(len(s) for s in col) for col in columns ]
template = ''.join(["{{{0}:>{1}d}}".format(i, w+padding) for i, w in enumerate(width)])
print "cells:", cells
print "scells:", scells
print "columns:", columns
print "width:", width
print "template:", template

for line in cells:
    print template.format(*line)
    
""" my output -->
cells: [[1, 5, 3, 1], [10, 23, 3, 23], [1, 122, 3, 233]]
scells: [['1', '5', '3', '1'], ['10', '23', '3', '23'], ['1', '122', '3', '233']]
columns: [('1', '10', '1'), ('5', '23', '122'), ('3', '3', '3'), ('1', '23', '233')]
width: [2, 3, 1, 3]
template: {0:>4d}{1:>5d}{2:>3d}{3:>5d}
   1    5  3    1
  10   23  3   23
   1  122  3  233
"""

Edited 5 Years Ago by Gribouillis: n/a

In that case it is pretty simple. You can just the format string % operator, see 5.6.2. String Formatting Operations. An example, and it looks like you've already padded by one space so I don't.

lens_list = [5, 3, 10]
data_list = [ [123, 17, 12345], [12, 18, 123456789], [2345, 1, 2]]

format_str = "Card"
for length in lens_list:
    format_str += "%"+str(length)+"d"
print format_str ## for your info

for data in data_list:
    print format_str % (data[0], data[1], data[2])

Thank you both for your replies. I haven't tried either of them out, but I'm sure I'll be able to work it out from the information you've given me. Greatly appreciated!

This article has been dead for over six months. Start a new discussion instead.