You can do this using the str.format() method.
Copy>>> width = 20
>>> print("{:>{width}} : {:>{width}}".format("Python", "Very Good", width=width))
Python : Very Good
Starting from Python 3.6 you can use f-string to do this:
CopyIn [579]: lang = 'Python'
In [580]: adj = 'Very Good'
In [581]: width = 20
In [582]: f'{lang:>{width}}: {adj:>{width}}'
Out[582]: ' Python: Very Good'
Answer from Sede on Stack OverflowYou can do this using the str.format() method.
Copy>>> width = 20
>>> print("{:>{width}} : {:>{width}}".format("Python", "Very Good", width=width))
Python : Very Good
Starting from Python 3.6 you can use f-string to do this:
CopyIn [579]: lang = 'Python'
In [580]: adj = 'Very Good'
In [581]: width = 20
In [582]: f'{lang:>{width}}: {adj:>{width}}'
Out[582]: ' Python: Very Good'
You can fetch the padding value from the argument list:
Copyprint '%*s : %*s' % (20, "Python", 20, "Very Good")
You can even insert the padding values dynamically:
Copywidth = 20
args = ("Python", "Very Good")
padded_args = zip([width] * len(args), args)
# Flatten the padded argument list.
print "%*s : %*s" % tuple([item for list in padded_args for item in list])
Videos
Using no packages and no modules:
nums= [[ 3, 4, -4, -8, -10, -12,], [ 5, 5, 3, -3, -4, -44,], [ 34,-4,-34, -22, 22, 22]]
t = ['|' + ''.join('%4i' % i for i in row) + ' |' for row in nums]
hdr = '+' + (len(t[0])-2) * '-' + '+'
print '\n'.join( [hdr] + t + [hdr] )
This produces the output:
+-------------------------+
| 3 4 -4 -8 -10 -12 |
| 5 5 3 -3 -4 -44 |
| 34 -4 -34 -22 22 22 |
+-------------------------+
How it works:
t = ['|' + ''.join('%4i' % i for i in row) + ' |' for row in nums]tcontains everything except the top and bottom rows. At its heart, the numbers are formatted as fixed width and aligned according to specification%4i.%4imeans allow four spaces, format as an integer, and align right. Many other specifications are possible. If you wanted, for example, to 5-space wide integers aligned left, use%-5i.hdr = '+' + (len(t[0])-2) * '-' + '+'Now that the interior rows are saved in
t, we can assemble the header and trailer lines. These lines begin and end with a plus sign. The rest are filled with-.print '\n'.join( [hdr] + t + [hdr] )This adds the
hdrstring to the beginning and end of the list of rowstand then joins all the rows together with newline characters to make the final table.
More complex example
Let's format the above table but add the min, max, mean, and standard deviation for each row at the end of each row.
def mmmsd(row):
mean=sum(row)/len(row)
stddev = ( sum( (x-mean)**2.0 for x in row ) / float(len(row)) )**0.5
return '%6i%6i%6.2f%6.2f' % (min(row), max(row), mean, stddev)
nums= [[ 3, 4, -4, -8, -10, -12,], [ 5, 5, 3, -3, -4, -44,], [ 34,-4,-34, -22, 22, 22]]
stats = [mmmsd(row) for row in nums]
t = [10*' ' + '|' + ''.join('%6i' % i for i in row) + ' |' + st for row, st in zip(nums, stats)]
hdr = 10*' ' + '+' + (len(t[0])-12 - len(stats[0])) * '-' + '+' + len(stats[0]) * ' '
print '\n'.join( [hdr] + t + [hdr] )
This produces the result:
+-------------------------------------+
| 3 4 -4 -8 -10 -12 | -12 4 -5.00 6.18
| 5 5 3 -3 -4 -44 | -44 5 -7.00 17.23
| 34 -4 -34 -22 22 22 | -34 34 3.00 24.92
+-------------------------------------+
This is what I like about Python - there is always something stopping you from reinventing the wheel.
For your use case, prettytable is a good fit:
import prettytable
l = [
[3, 4, -4, -8, -10, -12],
[5, 5, 3, -3, -4, -44],
[34, -4, -34, -22, 22, 22]
]
table = prettytable.PrettyTable(header=False, vrules=prettytable.FRAME)
for row in l:
table.add_row(row)
print table
Prints:
+----+----+-----+-----+-----+-----+
| 3 | 4 | -4 | -8 | -10 | -12 |
| 5 | 5 | 3 | -3 | -4 | -44 |
| 34 | -4 | -34 | -22 | 22 | 22 |
+----+----+-----+-----+-----+-----+
Also check Manually changing table style paragraph of the package documentation page.
There is also texttable, but it is less powerful in terms of tweaking the table look&feel:
import texttable
l = [
[3, 4, -4, -8, -10, -12],
[5, 5, 3, -3, -4, -44],
[34, -4, -34, -22, 22, 22]
]
table = texttable.Texttable()
table.add_rows(l, header=False)
print table.draw()
Prints:
+----+----+-----+-----+-----+-----+
| 3 | 4 | -4 | -8 | -10 | -12 |
+----+----+-----+-----+-----+-----+
| 5 | 5 | 3 | -3 | -4 | -44 |
+----+----+-----+-----+-----+-----+
| 34 | -4 | -34 | -22 | 22 | 22 |
+----+----+-----+-----+-----+-----+
Another option is tabulate which introduces a set of pre-defined table formats, e.g. "grid":
from tabulate import tabulate
l = [
[3, 4, -4, -8, -10, -12],
[5, 5, 3, -3, -4, -44],
[34, -4, -34, -22, 22, 22]
]
table = tabulate(l, tablefmt="grid")
print table
Prints:
+----+----+-----+-----+-----+-----+
| 3 | 4 | -4 | -8 | -10 | -12 |
+----+----+-----+-----+-----+-----+
| 5 | 5 | 3 | -3 | -4 | -44 |
+----+----+-----+-----+-----+-----+
| 34 | -4 | -34 | -22 | 22 | 22 |
+----+----+-----+-----+-----+-----+
Also see relevant threads:
- Formatting text in tabular form with Python
- A Text Table Writer/Printer for Python
You just need more cowbells (actually, more replacements: {}):
print "This is a number with {1} places {0:.{1}f}".format(3.14159, 2)
Or, in the example you gave:
C = ['{0:.{1}f}'.format(b, len(a.partition('.')[2])) for a,b in zip(A,B)]
With classical string formatting:
>>> d = 2
>>> f = "%%.%sf" % d
>>> f
'%.2f'
>>> f % 5.0
'5.00'
That is, first dynamically create your format string, and then use that format string for converting your float to a string. That concept is translatable to the modern string formatting syntax.