'How to format(align) a variable amount of data

I am trying to format data to be a certain amount of spaces apart, which would be very simple if it were a strict number of inputs, but it can vary. For example, this is what I have:

for i in LongPerEq:
     string = string + '%' + str(i) + 's '
# Where string is now '%6s %8s %9s'
line1 = string % (equations[0][0], equations[1][0], equations[2][0])
return(line1)

As you can see, I was able to make the 'string' variable into a string that will align them all properly, and it doesn't depend on the amount of 'equations' I want to use. So that part is good. The problem is the part where I have

 % (equations[0][0], equations[1][0], equations[2][0])

This is an issue because as it is, it is stuck being used for only 3 equations. It should be usable for 1, 2, 4, and 5. Hopefully this explained the issue I am having... any help would be greatly appreciated!



Solution 1:[1]

This might be a two part answer. The first part is how you can make the tuple you pass to the format operator '%' more flexible. Here's a bit of sample code:

equations = [ [ 1,2,3] , [4,5,6] , [7,8,9], [10,11,12] ]
string = "%6s %8s %9s"
line1 = string % ( equations[0][0], equations[1][0], equations[2][0]  ) 
print(line1)

# Here I am illustrating that this works for arbitrary sized equations list
string = "%6s %8s %9s %11s"
line2 = string  % tuple( e[0] for e in equations )
print(line2)

Above, you can see that we build the format tuple dynamically from all of the first element of equations.

However you may consider just concatenating line as shown below:

Not sure if you can enumerate LongPerfEq, so I wrote this snippet:

ndx = 0 
line1 = ""
for i in LongPerfEq:
  string = '%' + str(i) + 's '
  line1 += string % (equations[ndx])
  ndx += 1
return(line1)

Alternatively, you avoid adding ndx initializer and incrementer if enumerate works for you:

line1 = ""
for ndx,i in enumerate(LongPerfEq):
  string = '%' + str(i) + 's ' 
  line1 += string % (equations[ndx]) 
return(line1)

And perhaps you may want to look into the string.format().

Since format() is a function, you can unpack arguments into it (rather than creating a tuple to pass to the % operator).

Here's an example:

string="{0:>6s} {1:>8s} {2:>9s}  {3:>11s}" 
print( string.format( *[ e[0] for e in equations ] )  )

We are using a list comprehension to select the 0 element of each member of equations, and then we unpack the list using * so now format is getting each list element as an argument.

As I was playing with the new format syntax (i.e {0:>6s} vs. %6s ) I observed that strings are left justified by default, so I added the > specifier to get it to be right justified. The format {0:>6s} means, take the first (0th) element and format it as a right justified string of at least six characters.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1