4

I would like to format my integers as strings so that, without the sign, they will be zero-padded to have at least two digits.

For example I want

1
-1
10
-10

to be

01
-01
10
-10

Specifically, I want different minimum string lengths for negative numbers (3) and non-negative numbers (2). Simple number padding as detailed here is insufficient. Is this possible?

carmander
  • 61
  • 1
  • 1
  • 6
  • 1
    See http://pyformat.info, in particular [padding numbers](https://pyformat.info/#number_padding) – Peter Wood Feb 08 '17 at 13:42
  • @PeterWood I've read that webpage over and over again, nothing in there address my problem, which is that I require different minimum length strings for positive and negative numbers respectively. – carmander Feb 08 '17 at 14:39
  • 1
    put what you have tried in the question, and explain why it is inadequate. – Peter Wood Feb 08 '17 at 14:49
  • @PeterWood Thanks. Understood. This is the first question I asked so apologies for the incomplete question. It would be greatly appreciated if comments worked too. – carmander Feb 08 '17 at 14:55

6 Answers6

7

you could use str.format, but adding 1 to the size to take the negative number into account here:

l = [1,-1,10,-10,4]

new_l = ["{1:0{0}d}".format(2 if x>=0 else 3,x) for x in l]

print(new_l)

result:

['01', '-01', '10', '-10', '04']

it works because format accepts nested expressions: you can pass the size ({:02d} or {:03d}) as a format item too when saves the hassle of formatting the format string in a first pass.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
7

According to here, you need a space before the type descriptor, so both

'% d'%(1)

and

'{: d}'.format(1)

result in (notice the space)

' 1'

aligning nicely with the result of the above called with -1:

'-1'
Alex Thomas
  • 71
  • 1
  • 1
1

The most concise, although maybe a bit unreadable, way that I can think of (at least in Python 3) would be a formatted string literal with nested curly braces, similar to the accepted answer. With this, the example from the accepted answer could be written as

l = [1, -1, 10, -10, 4]
new_l = [f"{x:0{2 + (x < 0)}d}" for x in l]
print(new_l)

with the same result:

['01', '-01', '10', '-10', '04']
simon
  • 1,503
  • 8
  • 16
1

Use zfill:

inp_list = [1,-1,10,-10,4]

out_list = [str(n).zfill(3 if n<0 else 2) for n in inp_list]

print(out_list)

result:

['01', '-01', '10', '-10', '04']
-1

Use "{:03d}".format(n). The 0 means leading zeros, the 3 is the field width. May not be exactly what you want:

>>> for n in (-123,-12,-1,0,1,12,123, 1234):
...   print( '{:03d}'.format(n) )
... 
-123
-12
-01
000
001
012
123
1234
nigel222
  • 7,582
  • 1
  • 14
  • 22
-1

zfill actually pads with zeros at the left and considers negative numbers.

So n.zfill(3 if n < 0 else 2) would do the trick.

Newage99
  • 1
  • 1