429

I need to add leading zeros to integer to make a string with defined quantity of digits ($cnt). What the best way to translate this simple function from PHP to Python:

function add_nulls($int, $cnt=2) {
    $int = intval($int);
    for($i=0; $i<($cnt-strlen($int)); $i++)
        $nulls .= '0';
    return $nulls.$int;
}

Is there a function that can do this?

Matthew Schinckel
  • 35,041
  • 6
  • 86
  • 121
ramusus
  • 7,789
  • 5
  • 38
  • 45

10 Answers10

824

You can use the zfill() method to pad a string with zeros:

In [3]: str(1).zfill(2)
Out[3]: '01'
  • 3
    Is there a way to do the same only return an actual integer like 004 not a string like '004'? – Ajay Jul 29 '14 at 20:10
  • 72
    @Ajay 004 isn't an actual integer – Alvaro Jan 29 '15 at 18:37
  • 2
    Why is 004 not an integer? Python says `004 == 4` is true, and as far as I know mathematics agrees. – Mark Aug 28 '15 at 08:33
  • 24
    The way `004` is parsed by the compiler, and then represented in memory, is exactly the same as `4`. The only time a difference is visible is in the `.py` source code. If you need to store information like "format this number with leading zeros until the hundreds place", integers alone cannot provide that - you need to use alternate data structures (string work well in this case) – Gershom Maes Nov 11 '15 at 16:20
  • 30
    Need to say that this is not correct. The fact that `004 == 4` is kinda fortune. The way interpreter (python is not compiled) parses ints is different for ints starting with a leading `0`. If a number starts with `0` then it is considered as 8-nary number. So yeah, `004 == 4`, but `040 != 40` because `040 = 4 * 8 + 0 = 32`. – sbeliakov Jan 09 '17 at 15:01
  • 14
    To clarify a couple of things: 1. That is true only for parsing of integer literals, not for conversion of strings to ints - eg. if you do a = 010 then the value of a will be 8 but if you do a = int("010") the value of a will be 10. 2. Only Python 2 behaves this way - in python 3, a = 010 would give a syntax error. Octals in python 3 start with 0o, eg. 0o10 (presumably to avoid this exact confusion). – Tom Mar 31 '17 at 08:58
  • 2
    Thank you! I used this to display time via an f'string without pulling in a time library i.e instead of displaying 12:7 I was able to display 12:07 with the following code final_min = str(final_min).zfill(2) new_time = f'{final_hr}:{final_min}' – Heather Claxton Jan 18 '21 at 18:49
257

The standard way is to use format string modifiers. These format string methods are available in most programming languages (via the sprintf function in c for example) and are a handy tool to know about.

To output a string of length 5:


... in Python 3.5 and above: f-strings.

i = random.randint(0, 99999)
print(f'{i:05d}')

Search for f-strings here for more details.


... Python 2.6 and above:

print '{0:05d}'.format(i)

... before Python 2.6:

print "%05d" % i

See: https://docs.python.org/3/library/string.html

zabop
  • 6,750
  • 3
  • 39
  • 84
user518450
  • 2,948
  • 1
  • 17
  • 8
  • 1
    So what if you don't know the number of zeros before runtime? Let's say the length of a list? – Zelphir Kaltstahl Aug 16 '15 at 23:26
  • 4
    @Zelphir you can dynamically create the formatting string, `[('{{0:0{0:d}d}}').format(len(my_list)).format(k) for k in my_list]` – Mark Aug 28 '15 at 08:31
  • 1
    I've chosen to concat the format string instead, inserting the length of a list for example. Are there any advantages of your way of doing it? – Zelphir Kaltstahl Aug 29 '15 at 10:19
  • 4
    There is no need to use `str.format()` when all the template contains is one `{...}` placeholder. Avoid parsing the template and use the `format()` function instead: `format(i, '05d')` – Martijn Pieters Sep 29 '16 at 19:01
  • 2
    @Mark There is no need to use nested/stacked formats. The number of digits can be variable: `[('{0:0{1}d}').format(k, len(my_list)) for k in my_list]` --- with f-string: `[f'{k:0{len(my_list)}d}' for k in my_list]` --- It is weird that the number of digits is determined by the number of items. You probably want to prepare `max_digits` and use `[f'{k:0{max_digits}d}' for k in my_list]` – pabouk - Ukraine stay strong Jun 20 '22 at 08:44
123

Python 3.6 f-strings allows us to add leading zeros easily:

number = 5
print(f' now we have leading zeros in {number:02d}')

Have a look at this good post about this feature.

SergioAraujo
  • 11,069
  • 3
  • 50
  • 40
79

You most likely just need to format your integer:

'%0*d' % (fill, your_int)

For example,

>>> '%0*d' % (3, 4)
'004'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • 2
    The question is - how to add not permanent quantity of zeros – ramusus Apr 09 '09 at 09:20
  • 3
    This is not permanent - in fact you cannot add zeroes permanently to the from of an int - that would then be interpreted as an octal value. – Matthew Schinckel Apr 09 '09 at 11:56
  • 3
    @Matthew Schnickel: I think the OP wants to know a method to compute the number of zeros he needs. Formatting handles that fine. And int(x, 10) handles the leading zeros. –  Apr 09 '09 at 12:15
24

Python 2.6 allows this:

add_nulls = lambda number, zero_count : "{0:0{1}d}".format(number, zero_count)

>>>add_nulls(2,3)
'002'
clorz
  • 1,103
  • 3
  • 14
  • 30
21

For Python 3 and beyond: str.zfill() is still the most readable option

But it is a good idea to look into the new and powerful str.format(), what if you want to pad something that is not 0?

    # if we want to pad 22 with zeros in front, to be 5 digits in length:
    str_output = '{:0>5}'.format(22)
    print(str_output)
    # >>> 00022
    # {:0>5} meaning: ":0" means: pad with 0, ">" means move 22 to right most, "5" means the total length is 5

    # another example for comparision
    str_output = '{:#<4}'.format(11)
    print(str_output)
    # >>> 11##

    # to put it in a less hard-coded format:
    int_inputArg = 22
    int_desiredLength = 5
    str_output = '{str_0:0>{str_1}}'.format(str_0=int_inputArg, str_1=int_desiredLength)
    print(str_output)
    # >>> 00022
YunliuStorage
  • 479
  • 5
  • 14
8

You have at least two options:

  • str.zfill: lambda n, cnt=2: str(n).zfill(cnt)
  • % formatting: lambda n, cnt=2: "%0*d" % (cnt, n)

If on Python >2.5, see a third option in clorz's answer.

tzot
  • 92,761
  • 29
  • 141
  • 204
3

One-liner alternative to the built-in zfill.

This function takes x and converts it to a string, and adds zeros in the beginning only and only if the length is too short:

def zfill_alternative(x,len=4): return ( (('0'*len)+str(x))[-l:] if len(str(x))<len else str(x) )

To sum it up - build-in: zfill is good enough, but if someone is curious on how to implement this by hand, here is one more example.

Community
  • 1
  • 1
Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88
1

A straightforward conversion would be (again with a function):

def add_nulls2(int, cnt):
    nulls = str(int)
    for i in range(cnt - len(str(int))):
        nulls = '0' + nulls
    return nulls
rpr
  • 3,768
  • 2
  • 22
  • 20
-3

This is my Python function:

def add_nulls(num, cnt=2):
  cnt = cnt - len(str(num))
  nulls = '0' * cnt
  return '%s%s' % (nulls, num)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Emre Köse
  • 653
  • 6
  • 14