str.format() is making your fields left aligned within the available space. Use alignment specifiers to change the alignment:
'<'Forces the field to be left-aligned within the available space (this is the default for most objects).
'>'Forces the field to be right-aligned within the available space (this is the default for numbers).
'='Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form ‘+000000120’. This alignment option is only valid for numeric types.
'^'Forces the field to be centered within the available space.
Here's an example (with both left and right alignments):
>>> for args in (('apple', '$1.09', '80'), ('truffle', '$58.01', '2')):
... print '{0:<10} {1:>8} {2:>8}'.format(*args)
...
apple $1.09 80
truffle $58.01 2
Answer from Steven Rumbalski on Stack Overflowstr.format() is making your fields left aligned within the available space. Use alignment specifiers to change the alignment:
'<'Forces the field to be left-aligned within the available space (this is the default for most objects).
'>'Forces the field to be right-aligned within the available space (this is the default for numbers).
'='Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form ‘+000000120’. This alignment option is only valid for numeric types.
'^'Forces the field to be centered within the available space.
Here's an example (with both left and right alignments):
>>> for args in (('apple', '$1.09', '80'), ('truffle', '$58.01', '2')):
... print '{0:<10} {1:>8} {2:>8}'.format(*args)
...
apple $1.09 80
truffle $58.01 2
With python3 f-strings (not your example but mine):
alist = ["psi", "phi", "omg", "chi1", "chi2", "chi3", "chi4", "chi5", "tau"]
for ar in alist:
print(f"{ar: >8}", end=" ")
print()
for ar in alist:
ang = ric.get_angle(ar)
print(f"{ang:8.4}", end=" ")
print()
generates
psi phi omg chi1 chi2 chi3 chi4 chi5 tau
4.574 -85.28 178.1 -62.86 -65.01 -177.0 80.83 8.611 115.3
Since Python 2.6+, you can use a format string in the following way to set the columns to a minimum of 20 characters and align text to right.
table_data = [
['a', 'b', 'c'],
['aaaaaaaaaa', 'b', 'c'],
['a', 'bbbbbbbbbb', 'c']
]
for row in table_data:
print("{: >20} {: >20} {: >20}".format(*row))
Output:
a b c
aaaaaaaaaa b c
a bbbbbbbbbb c
data = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]
col_width = max(len(word) for row in data for word in row) + 2 # padding
for row in data:
print "".join(word.ljust(col_width) for word in row)
a b c
aaaaaaaaaa b c
a bbbbbbbbbb c
What this does is calculate the longest data entry to determine the column width, then use .ljust() to add the necessary padding when printing out each column.
Trying to format a string into columns with python - Stack Overflow
python - How to print a list more nicely? - Stack Overflow
How do you print columns in python.
python - How to format into columns from a list using a function? - Stack Overflow
Two columns, separated by tabs, joined into lines. Look in itertools for iterator equivalents, to achieve a space-efficient solution.
import string
def fmtpairs(mylist):
pairs = zip(mylist[::2],mylist[1::2])
return '\n'.join('\t'.join(i) for i in pairs)
print fmtpairs(list(string.ascii_uppercase))
A B
C D
E F
G H
I J
...
Oops... got caught by S.Lott (thank you).
A more general solution, handles any number of columns and odd lists. Slightly modified from S.lott, using generators to save space.
def fmtcols(mylist, cols):
lines = ("\t".join(mylist[i:i+cols]) for i in xrange(0,len(mylist),cols))
return '\n'.join(lines)
This works
it = iter(skills_defs)
for i in it:
print('{:<60}{}'.format(i, next(it, "")))
See: String format examples
Is something like this acceptable?
>>> names = ["Firstname Lastname", "First Last", "Name Name"]
>>> scores = [49900, 93000, 6400]
>>> for i,v in enumerate(zip(names, scores)):
... name, score = v[0], v[1]
... print "% *d. % -*s %d" % (3, i, 30, name, score)
...
0. Firstname Lastname 49900
1. First Last 93000
2. Name Name 6400
Here the "name" field is padded with spaces to a max width of 30 characters.
Edit: I now see that the width of the font is also a problem. I did not realize that at first from your question. I'll leave this up in case future Googlers end up here for a different reason.
You have two options:
Change the font of the PyGTK label to a font that has equal width characters (not unreasonable in a game, it reminds us of the old arcade days). You can do this with
set_markupofpango.Layout.Use two labels next to each other and use the method
set_alignmentof the classpango.Layout. The first label aligns the name to the left, the second label contains the score and it aligns to the right. As long as their is enough space the names and scores will align nicely to the left and right respectively.
This answer uses the same method in the answer by @Aaron Digulla, with slightly more pythonic syntax. It might make some of the above answers easier to understand.
>>> for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):
>>> print '{:<30}{:<30}{:<}'.format(a,b,c)
exiv2-devel mingw-libs tcltk-demos
fcgi netcdf pdcurses-devel
msvcrt gdal-grass iconv
qgis-devel qgis1.1 php_mapscript
This can be easily adapt to any number of columns or variable columns, which would lead to something like the answer by @gnibbler. The spacing can be adjusted for screen width.
Update: Explanation as requested.
Indexing
foolist[::3] selects every third element of foolist. foolist[1::3] selects every third element, starting at the second element ('1' because python uses zero-indexing).
In [2]: bar = [1,2,3,4,5,6,7,8,9]
In [3]: bar[::3]
Out[3]: [1, 4, 7]
zip
Zipping lists (or other iterables) generates tuples of the elements of the the lists. For example:
In [5]: zip([1,2,3],['a','b','c'],['x','y','z'])
Out[5]: [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'c', 'z')]
together
Putting these ideas together we get our solution:
for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):
Here we first generate three "slices" of foolist, each indexed by every-third-element and offset by one. Individually they each contain only a third of the list. Now when we zip these slices and iterate, each iteration gives us three elements of foolist.
Which is what we wanted:
In [11]: for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):
....: print a,b,c
Out[11]: exiv2-devel mingw-libs tcltk-demos
fcgi netcdf pdcurses-devel
[etc]
Instead of:
In [12]: for a in foolist:
....: print a
Out[12]: exiv2-devel
mingw-libs
[etc]
Although not designed for it, the standard-library module in Python 3 cmd has a utility for printing a list of strings in multiple columns
import cmd
cli = cmd.Cmd()
cli.columnize(foolist, displaywidth=40)
Output:
exiv2-devel msvcrt
mingw-libs gdal-grass
tcltk-demos iconv
fcgi qgis-devel
netcdf qgis1.1
pdcurses-devel php_mapscript
You even then have the option of specifying the output location, with cmd.Cmd(stdout=my_stream)
I'm printing a large amount of lists containing 4 items in columns but I can't get them to line up. Does anyone know how to do this?
small sample of output: Aaila Aaliya Aamna Aamnaha Aanya Aarilynn Aarna Aarushi Aasiyah Aaya Abagayle Abang Abay Abbagayle Abbegael Abbegail Abbeygail Abbeygayle Abbigael Abbigale Abbigrace Abbygael Abeam Abeeha Abeera Abeg Abey Abi Abighail Abinash Aboul Abrar Abree Abriana Abrianna Abrieanna Abriel Abriella Abrielle Abual
You can use zip() like so:
>>> for v in zip(*tableData):
print (*v)
a 1 one
b 2 two
c 3 three
d 4 four
You can obviously improve the formatting (like @Holt did very well) but this is the basic way :)
You can use zip to transpose your table and then use a formatted string to output your rows:
row_format = '{:<4}' * len(tableData)
for t in zip(*tableData):
print(row_format.format(*t))