86

I just want fixed width columns of text but the strings are all padded right, instead of left!!?

 sys.stdout.write("%6s %50s %25s\n" % (code, name, industry))

produces

BGA                                BEGA CHEESE LIMITED   Food Beverage & Tobacco
BHP                               BHP BILLITON LIMITED                 Materials
BGL                               BIGAIR GROUP LIMITED Telecommunication Services
BGG           BLACKGOLD INTERNATIONAL HOLDINGS LIMITED                    Energy

but we want

BGA BEGA CHEESE LIMITED                                Food Beverage & Tobacco
BHP BHP BILLITON LIMITED                               Materials
BGL BIGAIR GROUP LIMITED                               Telecommunication Services
BGG BLACKGOLD INTERNATIONAL HOLDINGS LIMITED           Energy
John Mee
  • 50,179
  • 34
  • 152
  • 186
  • shweet! thanks... it had to be pretty simple. umm now with 3 simultaneous correct answers who gets the green tick? – John Mee Oct 02 '12 at 04:11

8 Answers8

136

You can prefix the size requirement with - to left-justify:

sys.stdout.write("%-6s %-50s %-25s\n" % (code, name, industry))
Matthew Trevor
  • 14,354
  • 6
  • 37
  • 50
51

This version uses the str.format method.

Python 2.7 and newer

sys.stdout.write("{:<7}{:<51}{:<25}\n".format(code, name, industry))

Python 2.6 version

sys.stdout.write("{0:<7}{1:<51}{2:<25}\n".format(code, name, industry))

UPDATE

Previously there was a statement in the docs about the % operator being removed from the language in the future. This statement has been removed from the docs.

Community
  • 1
  • 1
Marwan Alsabbagh
  • 25,364
  • 9
  • 55
  • 65
  • 5
    The old style is no longer going to be deprecated, I believe: http://bugs.python.org/issue14123 – Matthew Trevor Oct 02 '12 at 04:51
  • It looks like that issue is rejected. Stage: committed/rejected – Marwan Alsabbagh Oct 02 '12 at 06:50
  • That status is _also_ used to indicate "committed", which it definitely was because the changes were made to the documentation. What was "Old String Formatting Operations" in the 3.2 docs is now [printf-style String Formatting](http://docs.python.org/py3k/library/stdtypes.html#printf-style-string-formatting) in 3.3. The _possible_ deprecation warning - it actually said "_may_ go away", it was never definitive - is now absent from that section as well, replaced with a warning about it being "quirky". It's not going away. – Matthew Trevor Oct 02 '12 at 10:34
  • 2
    You are looking at a different part of the docs. The section [Old string formatting](http://docs.python.org/py3k/tutorial/inputoutput.html#old-string-formatting) is still there in 3.3 docs it's under the tutorial section not the library reference. and the statement "this old style of formatting will eventually be removed from the language" is still there. – Marwan Alsabbagh Oct 02 '12 at 14:11
  • 4
    @Matthew - Disinformation is false information intended to mislead. I doubt Marwan had any such intentions. – Nick Chammas Jan 21 '14 at 03:01
  • Why isn't this in the docs... I had to google to find this answer and discover that "<" is used for left alignment :| – Locane Aug 10 '16 at 17:32
33

With the new and popular f-strings in Python 3.6, here is how we left-align say a string with 16 padding length:

string = "Stack Overflow"
print(f"{string:<16}..")
Stack Overflow  ..

If you have variable padding length:

k = 20
print(f"{string:<{k}}..")
Stack Overflow      .. 

f-strings are more compact.

ksha
  • 2,007
  • 1
  • 19
  • 22
  • `str` is a built-in in Python, so using that as an object name isn't ideal. – alichaudry Sep 26 '19 at 15:29
  • 2
    You can also put the direction character `>`, `<`, `^` etc, as a variable, so after `a="<"`, you can use: `f"{string:{a}{k}"` – Thruston Mar 08 '20 at 21:33
  • 1
    It would have been helpful to add the option for what @user1767754 showed: the insertion of padding characters, e.g. by `f"{string:_<16}"` (the padding char in this case is '_'). – Stephan Geue Dec 01 '21 at 13:59
31
sys.stdout.write("%-6s %-50s %-25s\n" % (code, name, industry))

on a side note you can make the width variable with *-s

>>> d = "%-*s%-*s"%(25,"apple",30,"something")
>>> d
'apple                    something                     '
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
27

I definitely prefer the format method more, as it is very flexible and can be easily extended to your custom classes by defining __format__ or the str or repr representations. For the sake of keeping it simple, i am using print in the following examples, which can be replaced by sys.stdout.write.

Simple Examples: alignment / filling

#Justify / ALign (left, mid, right)
print("{0:<10}".format("Guido"))    # 'Guido     '
print("{0:>10}".format("Guido"))    # '     Guido'
print("{0:^10}".format("Guido"))    # '  Guido   '

We can add next to the align specifies which are ^, < and > a fill character to replace the space by any other character

print("{0:.^10}".format("Guido"))    #..Guido...

Multiinput examples: align and fill many inputs

print("{0:.<20} {1:.>20} {2:.^20} ".format("Product", "Price", "Sum"))
#'Product............. ...............Price ........Sum.........'

Advanced Examples

If you have your custom classes, you can define it's str or repr representations as follows:

class foo(object):
    def __str__(self):
        return "...::4::.."

    def __repr__(self):
        return "...::12::.."

Now you can use the !s (str) or !r (repr) to tell python to call those defined methods. If nothing is defined, Python defaults to __format__ which can be overwritten as well. x = foo()

print "{0!r:<10}".format(x)    #'...::12::..'
print "{0!s:<10}".format(x)    #'...::4::..'

Source: Python Essential Reference, David M. Beazley, 4th Edition

user1767754
  • 23,311
  • 18
  • 141
  • 164
9

Use -50% instead of +50% They will be aligned to left..

The6thSense
  • 8,103
  • 8
  • 31
  • 65
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
7

A slightly more readable alternative solution:
sys.stdout.write(code.ljust(5) + name.ljust(20) + industry)

Note that ljust(#ofchars) uses fixed width characters and doesn't dynamically adjust like the other solutions.

(Also note that string addition with + is significantly faster in modern Python than it was in the past, but you can swap out + with ''.join(...) if you still prefer that method out of habit)

Nick Sweeting
  • 5,364
  • 5
  • 27
  • 37
4

This one worked in my python script:

print "\t%-5s %-10s %-10s %-10s %-10s %-10s %-20s"  % (thread[0],thread[1],thread[2],thread[3],thread[4],thread[5],thread[6])
  • 1
    Not sure what this adds in terms of differentiation from anything else. and what the heck is thread array? – UpAndAdam Nov 12 '13 at 17:32