6

I want to be able to be able to format date/time input for my function.

Currently, I have a function that basically appends a 0 to a number if it is only 1 digit long.

def format_num(str(num)):
    if len(num) < 2:
        return "0" + num
    return num

I was wondering if there was a more pythonic way to do this.

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
Liondancer
  • 15,721
  • 51
  • 149
  • 255
  • 2
    Here you go: python -c 'print("%02d" % 1)' – Javier Nov 10 '14 at 17:35
  • https://docs.python.org/2/library/string.html#formatspec – Paulo Scardine Nov 10 '14 at 17:35
  • "Format for a datetime" - why not [format](https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior) your datetime object (`%d` or `%m` for day / month) – Andy Nov 10 '14 at 17:36
  • 1
    Generally speaking: `format(num, '02d')` or `str(num).zfill(2)`, but for *datetime* objects there are better ways still. Do you have `datetime` objects here? – Martijn Pieters Nov 10 '14 at 17:36
  • @Javier: isn't the '%' operator deprecated in favor of `str.format`? – Paulo Scardine Nov 10 '14 at 17:38
  • AFAIK, both are supported. .format can also do that as Paulo referenced. – Javier Nov 10 '14 at 17:40
  • 1
    @PauloScardine - It is not officially *deprecated* (yet), but its use is discouraged in favor of `str.format`. I wouldn't be surprised if it is eventually removed from the language though (Python 4 maybe?). New code should use `str.format`. –  Nov 10 '14 at 17:41

4 Answers4

21

You could use the string method zfill to pad the strings with zeros to a specified width. Specify a width of 2:

>>> '1'.zfill(2)
'01'

Strings longer than one character won't be touched:

>>> '31'.zfill(2)
'31'
Alex Riley
  • 169,130
  • 45
  • 262
  • 238
5
>>> ["{:02}".format(num) for num in (1,22,333)]
['01', '22', '333']

See https://docs.python.org/2/library/string.html#formatspec for more on the syntax understood by the format method.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • 4
    Don't use `str.format()` where a simple `format()` would do. No need to parse out `{...}` placeholders and map to arguments that way. `format(num, '02')` or `format(num, '02d')`. – Martijn Pieters Nov 10 '14 at 17:37
  • @MartijnPieters TMTOWTDI. – zwol Nov 10 '14 at 17:38
  • @MartijnPieters Less flippantly, inevitably the OP will want to format more than one value into the same string, so it's better to teach the syntax that generalizes more easily. – zwol Nov 10 '14 at 17:40
  • Sure, but then do so explicitly and talk about the difference. – Martijn Pieters Nov 10 '14 at 17:40
4

Calling string format functions is several times slower than

>>> "%02d" % 8
'08'
>>> "%02d" % 80
'80'

So if you care about performance try to avoid function calls.

python -m timeit "'%02d' % 8"
100000000 loops, best of 3: 0.0166 usec per loop

python -m timeit "'8'.zfill(2)"
10000000 loops, best of 3: 0.163 usec per loop

python -m timeit "'{:02}'.format(2)"
1000000 loops, best of 3: 0.385 usec per loop

In such simple and often called code, I would take the faster solution.

wenzul
  • 3,948
  • 2
  • 21
  • 33
3

To answer your direct question -

You can format your number like this:

format(num, '02d')

Example:

nums = [1,22,333]

for num in nums:
    print format(num, '02d')

Outputs:

01
22
333

However, you say that you are using a datetime. You can directly format a datetime object

%d - Zero padded day
%m - Zero padded month
Andy
  • 49,085
  • 60
  • 166
  • 233