# How do I pad numbers to the left so that all are the same length?

I have a list of numbers like

{-6, 1, 3, 23}


and want to get a list of strings, all of the same length, with zeros padding on the left as needed, like

{"-6", "01", "03", "23"}


The closest I can get following the documentation is with something like

NumberForm[{-6, 1, 3, 23}, 1, NumberPadding -> {"0", ""}]


which (astonishingly) produces

{"-6", "01", "03", "023"}


How I can simply get my strings to all be the same length, padded as needed with zeros?

• What do you desire for the first entry: "-06" or "0-6" or "-006"? Mar 3 '15 at 18:24
• @DavidG.Stork: "-6", as indicated: all the same length. Mar 3 '15 at 18:26
• Oh... it was unclear whether you wanted all strings to have the length 3 (in this case)... as in "023". Let me work on this.... Mar 3 '15 at 18:29
• IntegerString may come in handy. Mar 3 '15 at 18:41
• @DavidG.Stork: Just like the example. Never more than one digit negative numbers and never more than two digit positives. Mar 3 '15 at 18:51

As of 10.1 this is built in to Mathematica with StringPadLeft:

StringPadLeft[#,2,"0"]&@*ToString/@{-6,1,3,23}


{"-6", "01", "03", "23"}

• Could you please elucidate on the meaning of &@*? Sep 15 '19 at 1:41
• @Oscillon Composition Sep 15 '19 at 1:46
ClearAll[nF]
nF = With[{l = #, p = #2}, NumberForm[l, p, SignPadding -> True, NumberPadding -> {"0", ""},
NumberFormat -> (StringTake[#1, -(p + 1)] &)]] &;

nF[{-6, 1, 3, 23}, 1]
(* {-6, 01, 03, 23} *)

nF[{-6, 1, 3, 23, 123}, 2]
(* {-06, 001, 003, 023, 123} *)


Note: You can also use PaddedForm instead of NumberForm.

StringTake["0" <> ToString[#], -2] & /@ {-6, 1, 3, 23}


One way:

If[StringLength@# == 1, "0" <> #, #] &@*ToString /@ {-6, 1, 3, 23}


Another way:

StringJoin@*(ToString /@ PadLeft[#, 2] &)@*Characters@*ToString /@ {-6, 1, 3, 23}

• So there's no built-in way to do this? Any idea what the reasoning behind the way NumberForm works could possibly be? I really don't understand the philosophy behind the Mathematica language design (c.f.: [str(n).zfill(2) for n in numbers]). Mar 3 '15 at 18:42
• @raxacoricofallapatorius Take a look at the newest solution. There is a built in function, but in order to use it we must first convert our string into a list. Mar 3 '15 at 18:52
• So the second solution is incomplete. Mar 3 '15 at 18:58
• @raxacoricofallapatorius Argh, I forgot to convert it back into a string. Now it's less elegant; I'd go with the first option. I'd go with it anyway because it's easy to understand; if you look at it in 6 months you will still know what it does. Mar 3 '15 at 19:00
• Thanks. That works. I'm still puzzled what (if any) design philosophy could have lead to this sort of thing. [str(n).zfill(2) for n in numbers] is not only something I'll understand in 6 months, but something that I can remember to recreate in 6 months (or years). Mar 3 '15 at 19:05

just for fun..we can define a zfill function

 zfill[n_, f_String: "0"] :=
Function[{s},
StringJoin[ConstantArray[f, Max[0, n - StringLength[s]]], s]];


then the operation is quite similar to your python expression:

 zfill[2] /@ ToString /@ {-6, 1, 3, 23}


{"-6", "01", "03", "23"}

• I find this a good one! Mar 19 '15 at 10:32

Here is an answer that is loosely based upon kglr's previous answer. The below solution has been generalized to also handle decimal numbers and scientific form. Your example number list only contained small integers, but others who find this post may find the generalization useful.

The code:

AltNumberFormat[n_, f___,
opts : OptionsPattern[{NumberForm, "AltPadding" -> ""}]] := With[{
},
NumberForm[
N@n, f, FilterRules[{opts}, Options@NumberForm],
NumberFormat -> Function[{m, b, e}, With[
{s =
If[e == "", s, Row[{s, b^e}, "\[Times]"]]
]]]]


Usage is exactly the same as regular NumberForm, with the addition of an extra AltPadding option. This would usually be used if you wanted to pad with leading zeros (without the extra zeros!) but still get your numbers to left-align, by padding positive numbers with leading spaces.

Test cases:

hdr = Prepend[
Item[#, BaseStyle -> Bold, Background -> LightBlue] & /@ {"Input",

Row@Map[Grid[hdr@#, Frame -> All, Alignment -> Left,
Background -> {{4 -> LightYellow}}] &]@
Transpose@Flatten[#, 2] &@
Table[
{m*n, f, Style[p, ShowStringCharacters -> True],

Using sprintf that I describe in this answer, you can do Map[sprintf["%02i", #] &, {-6, 1, 3, 23}] to get {"-6", "01", "03", "23"}.