12
$\begingroup$

I have a list wich contains numbers and other lists, and what I want is to change every number x to {x,0}.

So if the function I'm seeking is called f, then

a = {1,Pi,2+3I,{1,2},{3,4},-2}

f[a] should be {{1,0},{Pi,0},{2+3I,0},{1,2},{3,4},{-2,0}}.

I tried doing all kinds of rules, but none of them work as I want. Any help would be appreciated. Thanks.

$\endgroup$
1
  • 5
    $\begingroup$ I assume the introduction of a sign in mapping of your last element from $2\to\{-2,0\}$ is a typo, should be $2\to\{2,0\}$ or $-2\to\{-2,0\}$? $\endgroup$ Sep 2, 2017 at 2:02

8 Answers 8

11
$\begingroup$

If[NumberQ[N[#]], {#, 0}, #] & /@ a

or

Replace[a, {b_ :> If[NumberQ[N[b]], {b, 0}, b]}, 1]

or

Replace[a, {b_ :> {b, 0} /; NumberQ[N[b]]}, 1]

or

a /. {{a_, b_} :> {a, b}, b_ :> {b, 0} /; NumberQ[N[b]]}

or the above with Element[b_,Complexes] i.e.

a /. {{a_, b_} :> {a, b}, b_ :> {b, 0} /; Element[b, Complexes]}

or

If[Element[#, Complexes] && !ListQ[#], {#, 0}, #] & /@ a

or

Replace[a, {b_ :> {b, 0} /; !ListQ[b] && Element[b, Complexes]}, 1]

etc.


Update: Based on Alucard's nice comment. If and only if elements strictly numbers or lists:

Flatten@*List/@a//PadRight



Update${}^{\mathbf 2}$: TIL: Besides brevity, Mr.Wizard's suggestion NumericQ definitely more efficient than NumberQ@*N.

Relatively inconsequential for simple numbers, but you can get creative:

someNumber = 
  Total[Table[(\[Pi] + I + GoldenAngle)^
      RandomInteger[{4, 
        1000}]/((\[Pi] - GoldenAngle + Exp[ I GoldenAngle])^
        RandomInteger[{4, 1000}] + (\[Pi] + GoldenAngle + 
          Exp[ I GoldenAngle])^RandomInteger[{4, 1000}]), {600}]];

RepeatedTiming[someNumber // N // NumberQ]

{0.01, True}

RepeatedTiming[NumericQ@someNumber]

{$2.3 \times 10^{-7}$, True}

$\endgroup$
3
  • $\begingroup$ I guess if you can really trust numbers xor lists as per taking strictly "contains numbers and other lists" only really have to test for ListQ, i.e. If[ListQ[#], #, {#, 0}] & /@ a $\endgroup$ Sep 2, 2017 at 2:52
  • 1
    $\begingroup$ or If[ ListQ[#], #, PadRight[{#}, 2]] & /@ a $\endgroup$
    – Alucard
    Sep 2, 2017 at 3:01
  • 3
    $\begingroup$ I believe you can replace NumberQ[N[#]] with NumericQ[#] in each application. $\endgroup$
    – Mr.Wizard
    Sep 2, 2017 at 7:10
4
$\begingroup$

Maybe this can help

PadRight[Charting`padList /@ a]

{{1,0},{π,0},{2+3 I,0},{1,2},{3,4},{-2,0}}

$\endgroup$
1
  • 2
    $\begingroup$ 你总是能搞出些奇怪的函数,(手动滑稽。不知到SE上有没有这个问题:有哪些奇怪的函数不常见,但是挺有用?我没搜到,要是没有的话可以问一个。 $\endgroup$ Sep 3, 2017 at 2:54
3
$\begingroup$
Transpose@Thread[PadRight[Flatten@*List /@ a]]   
$\endgroup$
3
$\begingroup$
  • You only want to replace numeric things, not lists.
  • You don't want to try to rewrite the entire list, just its elements, so you only want to replace subexpressions at level 1.

    Replace[a, b_?NumericQ -> {b, 0}, 1]

$\endgroup$
3
$\begingroup$
ClearAll[f]
f[x_]:={x,0}
f[{x___}]:={x}

f/@a

(*  {{1, 0}, {Pi, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}  *)
$\endgroup$
2
  • $\begingroup$ x_ will capture standalone strings as well? $\endgroup$
    – Syed
    Apr 15, 2023 at 9:58
  • 1
    $\begingroup$ The OP has a list which "contains numbers and other lists". If there are strings present (not specified), then this could be handled by (say) including f[x_String]:=x in the function definition $\endgroup$
    – user1066
    Apr 15, 2023 at 10:48
2
$\begingroup$
a = {1, Pi, 2 + 3 I, {1, 2}, {3, 4}, -2};

First compare the outputs of NumberQ and NumericQ applied to the input list.

{#, NumberQ@#} & /@ a

{{1, True}, {π, False}, {2 + 3 I, True}, {{1, 2}, False}, {{3, 4},
False}, {-2, True}}

{#, NumericQ@#} & /@ a

{{1, True}, {π, True}, {2 + 3 I, True}, {{1, 2}, False}, {{3, 4},
False}, {-2, True}}

π is a symbol, but has a numeric value. Furthermore, to exclude lists, Except can be used.

Replace[a, Except[_List, x_?NumericQ] :> {x, 0}, 1]

{{1, 0}, {π, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}

$\endgroup$
2
$\begingroup$
a = {1, Pi, 2 + 3 I, {1, 2}, {3, 4}, -2};

Using SequenceReplace (new in 11.3}

SequenceReplace[a, {x_?NumericQ} :> {x, 0}]

{{1, 0}, {π,, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}

Using SubsetReplace (new in 12.1}

SubsetReplace[a, {x_?NumericQ} :> {x, 0}]

{{1, 0}, {π,, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}

Using ReplaceAt (new in 13.1}

ReplaceAt[x_?NumericQ :> {x, 0}, All] @ a

{{1, 0}, {π,, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}

$\endgroup$
2
$\begingroup$
a = {1, Pi, 2 + 3  I, {1, 2}, {3, 4}, -2};

Using Cases and If:

Cases[a, n_ :> If[ListQ[n], n, {n, 0}]]

(*{{1, 0}, {π, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}*)

Or using Position and MapAt:

MapAt[{#, 0} &, a, Rest@Position[a, n_ /; Head[n] =!= List, 1]]

(*{{1, 0}, {π, 0}, {2 + 3 I, 0}, {1, 2}, {3, 4}, {-2, 0}}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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