str.zfill()

Added in v3.x · Updated March 13, 2026 · String Methods
stdlib string zfill

The .zfill() method pads a string on the left with zeros until it reaches the specified width. It’s particularly useful for formatting numbers, generating fixed-width identifiers, and ensuring consistent string lengths for display or processing.

Signature

str.zfill(width)

Parameters

ParameterTypeDefaultDescription
widthintThe total width of the returned string. If the string is already longer than width, it’s returned unchanged.

Return Value

Returns a new string of the specified width, padded with leading zeros. If the original string’s length equals or exceeds the width, a new string (identical to the original) is returned.

Examples

Basic Usage

>>> "42".zfill(4)
'0042'

>>> "hello".zfill(10)
'00000hello'

The method adds zeros to the left until the string reaches the target width. Strings shorter than the width get padded; strings equal to or longer than the width are returned as-is.

Number Formatting

>>> "7".zfill(3)
'007'

>>> "123".zfill(5)
'00123'

>>> "12345".zfill(3)
'12345'  # No padding needed

This is the classic use case—formatting numbers with leading zeros, similar to what you might see in timestamps or invoice numbers.

Handling Negative Numbers

>>> "-42".zfill(5)
'-0042'

>>> "-3".zfill(4)
'-003'

.zfill() preserves the minus sign and pads after it. The total width includes the sign character.

Padding Hexadecimal and Other Bases

>>> hex(255)[2:].zfill(4)
'00ff'

>>> hex(4096)[2:].zfill(6)
'001000'

Combine with string slicing to pad hexadecimal representations.

Practical Use Cases

Generating sequential IDs:

for i in range(1, 11):
    print(f"ID-{str(i).zfill(3)}")
# Output:
# ID-001
# ID-002
# ...
# ID-010

Formatting timestamps:

from datetime import datetime

now = datetime.now()
print(f"{now.hour.zfill(2)}:{now.minute.zfill(2)}")
# Output: "09:05" (for 9:05)

File naming with sequential numbers:

for i in range(100):
    filename = f"data_{str(i).zfill(4)}.csv"
    # Creates: data_0000.csv, data_0001.csv, ... data_0099.csv

Behavior Details

How It Works

The method calculates how many zeros to prepend by subtracting the current string length from the target width:

>>> s = "42"
>>> width = 4
>>> zeros_needed = width - len(s)  # 4 - 2 = 2
>>> "0" * zeros_needed + s  # "00" + "42" = "0042"

Sign Handling

The sign (if present) is preserved at the front, and zeros are inserted after it:

>>> "+42".zfill(5)
'+0042'

>>> "-42".zfill(5)
'-0042'

>>> "+0".zfill(3)
'+00'

Non-Numeric Strings

.zfill() works on any string, not just numbers:

>>> "abc".zfill(6)
'000abc'

>>> "".zfill(3)
'000'

>>> "test".zfill(0)
'test'  # Width 0 returns original

Edge Cases

>>> "".zfill(0)
''

>>> "hello".zfill(-1)
'hello'  # Negative width returns original (Python 3.11+)

>>> "001".zfill(3)
'001'  # Already at width, no change

Common Mistakes

Assuming it works like rjust with ‘0’:

# zfill is equivalent to rjust with '0' for most cases:
>>> "42".zfill(4)
'0042'

>>> "42".rjust(4, '0')
'0042'

# But rjust can use any character:
>>> "42".rjust(4, 'x')
'xx42'

Forgetting about sign characters:

# The width includes the sign
>>> "-1".zfill(3)   # width=3 gives '-01' (sign + 2 digits)
'-01'

>>> "-1".zfill(4)   # width=4 gives '-001' (sign + 3 digits)  
'-001'

Using with floats:

# zfill doesn't work directly on floats
>>> "3.14".zfill(6)
'03.14'  # This works but may not be what you want

# For floats, convert to string first or use formatting:
>>> f"{3.14:05.2f}"
'03.14'

Performance

.zfill() creates a new string, so memory usage scales with the result size. It’s implemented in C and runs in O(n) time where n is the width. For most use cases with reasonable widths (under 1000 characters), performance is negligible.

See Also

  • .ljust() — Pad a string on the right with a specified character
  • .rjust() — Pad a string on the left with a specified character
  • .strip() — Remove leading/trailing characters