How to Pad a String with Zeros in Python

The quickest way to pad a string with zeros in Python is str.zfill(width): it adds zeros on the left until the string is width characters long and keeps a leading + or - in front. For zeros on the right, use ljust(width, "0"):

"42".zfill(5)        # '00042'
"1.5".ljust(5, "0")  # '1.500'

I checked every result with Python 3.12.5 and pandas 3.0.6, using order IDs and ZIP codes as the example strings.

You’ll see zfill, the rjust and ljust alternatives, the f-string rule that catches people out with strings, ZIP codes that lose their zeros in pandas, and how to remove leading zeros again.

Pad a string with zeros using zfill()

zfill() is built for exactly this job. Strings already at or over the width come back unchanged, so it never truncates:

order_ids = ["7", "42", "305", "12345", "1234567"]
for oid in order_ids:
    print(f"{oid:>8} -> {oid.zfill(5)}")

print("-42".zfill(6), "+7".zfill(4), "3.5".zfill(6))   # sign stays in front

Output:

       7 -> 00007
      42 -> 00042
     305 -> 00305
   12345 -> 12345
 1234567 -> 1234567
-00042 +007 0003.5
Command Prompt output of Python zfill padding order ID strings with leading zeros and keeping the sign in front
Short IDs get zeros up to five characters; longer ones are left alone, and signs stay at the front.

If you’re starting from an integer rather than a string, format it directly instead; my guide on padding numbers with leading zeros in Python covers that side.

Pad with zeros on the left or right using rjust() and ljust()

rjust(), ljust() and center() take any fill character. The difference from zfill() shows up with signs:

code = "-42"
print("zfill:     ", code.zfill(6))
print("rjust '0': ", code.rjust(6, "0"))      # zeros go before the minus sign
print("ljust '0': ", "1.5".ljust(6, "0"))     # pad on the right
print("center '0':", "TX".center(6, "0"))

Output:

zfill:      -00042
rjust '0':  000-42
ljust '0':  1.5000
center '0': 00TX00
Command Prompt output comparing Python zfill and rjust with a zero fill on a negative string, plus ljust and center
rjust() puts zeros in front of the minus sign, giving 000-42; zfill() gives -00042.

Use ljust(width, "0") for trailing zeros, like fixed-width decimal fields. For general text, building fixed-width strings is covered in creating a string of N characters in Python.

Why does an f-string pad my string with zeros on the right?

For numbers, {n:05} pads on the left. For strings, the same spec pads on the right, because strings align left by default. Add > to fix it:

s = "42"
n = 42

print(f"{n:05}")       # int: zero-padded on the left  -> 00042
print(f"{s:05}")       # str: '0' is just the fill, and strings align LEFT -> 42000
print(f"{s:0>5}")      # say > to right-align a string -> 00042
print(f"{s:0<5}")      # right padding on purpose      -> 42000

width = 8
print(f"{'A-17':0>{width}}")        # width from a variable
print("{:0>6}".format("731"))       # same rules in str.format

Output:

00042
42000
00042
42000
0000A-17
000731
Command Prompt output of Python f-strings padding an int and a string with zeros, showing strings padded on the right unless > is used
The same :05 gives 00042 for the int and 42000 for the string.

So for strings I always write the alignment explicitly: :0>5 for leading zeros. Formatting rules in general are in creating a string with variables in Python.

Keep leading zeros in ZIP codes and IDs with pandas

Leading zeros usually vanish before you ever pad anything: a CSV reader sees 02134 and stores the number 2134. Here’s that happening in pandas, and two fixes:

import io
import pandas as pd

csv = "customer,zip\nEmily,02134\nJames,07030\nOlivia,73301\n"

wrong = pd.read_csv(io.StringIO(csv))
print(wrong["zip"].tolist(), wrong["zip"].dtype)            # leading zeros gone

fixed = wrong["zip"].astype(str).str.zfill(5)
print(fixed.tolist())

right = pd.read_csv(io.StringIO(csv), dtype={"zip": str})   # best: never lose them
print(right["zip"].tolist(), right["zip"].dtype)

Output:

[2134, 7030, 73301] int64
['02134', '07030', '73301']
['02134', '07030', '73301'] str
Command Prompt output of pandas reading ZIP codes as integers and losing leading zeros, then str.zfill and dtype=str keeping them
Read as integers, Boston’s 02134 becomes 2134. str.zfill(5) restores it, but reading the column as text is the real fix.

The same thing happens with phone extensions, product codes and account numbers. If the data comes from a text file first, see reading a file as a string in Python.

Remove leading zeros from a string

Going the other way, lstrip("0") removes leading zeros, but it has two traps: an all-zero string becomes empty, and it doesn’t understand signs. Converting to a number avoids both:

values = ["000042", "0000", "0.50", "-0042"]
for v in values:
    print(f"{v!r:>9} lstrip -> {v.lstrip('0')!r:>7}   int/float -> {float(v) if '.' in v else int(v)}")

Output:

 '000042' lstrip ->    '42'   int/float -> 42
   '0000' lstrip ->      ''   int/float -> 0
   '0.50' lstrip ->   '.50'   int/float -> 0.5
  '-0042' lstrip -> '-0042'   int/float -> -42

Use int() when the value is really a number, and lstrip() only for codes. Turning text into numbers safely is covered in converting a string to an integer in Python.

Zero-padding methods compared

MethodPadsHandles + / –Example
s.zfill(5)LeftYes'-42' → '-0042'
s.rjust(5, "0")LeftNo'-42' → '00-42'
s.ljust(5, "0")RightNo'1.5' → '1.500'
f"{s:0>5}"LeftNo'42' → '00042'
Series.str.zfill(5)LeftYespandas columns

These string guides are worth a look next:

Frequently asked questions

How do I pad a string with zeros in Python?

Use s.zfill(width), for example "42".zfill(5) gives '00042'.

How do I add zeros to the right of a string?

Use s.ljust(width, "0") or f"{s:0<width}".

Why does f”{s:05}” add zeros at the end?

Strings are left-aligned by default. Use f"{s:0>5}" to put the zeros in front.

Does zfill work with negative numbers?

Yes. "-42".zfill(5) gives '-0042', keeping the sign first. rjust() doesn’t.

How do I keep leading zeros when reading a CSV?

Read the column as text, for example pd.read_csv(path, dtype={"zip": str}).

Where is str.zfill documented?

See str.zfill() in the Python docs.