8
$\begingroup$

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?

$\endgroup$
  • 1
    $\begingroup$ What do you desire for the first entry: "-06" or "0-6" or "-006"? $\endgroup$ – David G. Stork Mar 3 '15 at 18:24
  • $\begingroup$ @DavidG.Stork: "-6", as indicated: all the same length. $\endgroup$ – orome Mar 3 '15 at 18:26
  • $\begingroup$ 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.... $\endgroup$ – David G. Stork Mar 3 '15 at 18:29
  • 1
    $\begingroup$ IntegerString may come in handy. $\endgroup$ – Yves Klett Mar 3 '15 at 18:41
  • 1
    $\begingroup$ @DavidG.Stork: Just like the example. Never more than one digit negative numbers and never more than two digit positives. $\endgroup$ – orome Mar 3 '15 at 18:51
9
$\begingroup$

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

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

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

$\endgroup$
  • $\begingroup$ Could you please elucidate on the meaning of &@*? $\endgroup$ – Oscillon Sep 15 at 1:41
  • 1
    $\begingroup$ @Oscillon Composition $\endgroup$ – orome Sep 15 at 1:46
5
$\begingroup$
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.

$\endgroup$
4
$\begingroup$

Taking under consideration your assumptions:

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

One way:

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

Another way:

StringJoin@*(ToString /@ PadLeft[#, 2] &)@*Characters@*ToString /@ {-6, 1, 3, 23}
$\endgroup$
  • $\begingroup$ 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]). $\endgroup$ – orome Mar 3 '15 at 18:42
  • $\begingroup$ @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. $\endgroup$ – C. E. Mar 3 '15 at 18:52
  • $\begingroup$ So the second solution is incomplete. $\endgroup$ – orome Mar 3 '15 at 18:58
  • $\begingroup$ @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. $\endgroup$ – C. E. Mar 3 '15 at 19:00
  • $\begingroup$ 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). $\endgroup$ – orome Mar 3 '15 at 19:05
1
$\begingroup$

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"}

$\endgroup$
  • $\begingroup$ I find this a good one! $\endgroup$ – Santi Mar 19 '15 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.