Recursively turn expression into nested list

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite












I've been trying to write a simple function that turns an expression into a nested list. So for example, a+2b+3c becomes a,2,b,3,c. This is what I wrote:



toList[x_] := Module[, 
x = List@@x;
For[i=1, i <= Length[x]; i++,
If[x[[i]] != List@@x[[i]], x[[i]] = toList[x[[i]]]]
];
x
]


However, I keep getting errors like "Tag Plus in a+2b+3c is protected" and "a+2b+3c in the part assignment is not symbol." How can I fix what's going wrong?







share|improve this question


























    up vote
    4
    down vote

    favorite












    I've been trying to write a simple function that turns an expression into a nested list. So for example, a+2b+3c becomes a,2,b,3,c. This is what I wrote:



    toList[x_] := Module[, 
    x = List@@x;
    For[i=1, i <= Length[x]; i++,
    If[x[[i]] != List@@x[[i]], x[[i]] = toList[x[[i]]]]
    ];
    x
    ]


    However, I keep getting errors like "Tag Plus in a+2b+3c is protected" and "a+2b+3c in the part assignment is not symbol." How can I fix what's going wrong?







    share|improve this question
























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I've been trying to write a simple function that turns an expression into a nested list. So for example, a+2b+3c becomes a,2,b,3,c. This is what I wrote:



      toList[x_] := Module[, 
      x = List@@x;
      For[i=1, i <= Length[x]; i++,
      If[x[[i]] != List@@x[[i]], x[[i]] = toList[x[[i]]]]
      ];
      x
      ]


      However, I keep getting errors like "Tag Plus in a+2b+3c is protected" and "a+2b+3c in the part assignment is not symbol." How can I fix what's going wrong?







      share|improve this question














      I've been trying to write a simple function that turns an expression into a nested list. So for example, a+2b+3c becomes a,2,b,3,c. This is what I wrote:



      toList[x_] := Module[, 
      x = List@@x;
      For[i=1, i <= Length[x]; i++,
      If[x[[i]] != List@@x[[i]], x[[i]] = toList[x[[i]]]]
      ];
      x
      ]


      However, I keep getting errors like "Tag Plus in a+2b+3c is protected" and "a+2b+3c in the part assignment is not symbol." How can I fix what's going wrong?









      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 2 at 13:29

























      asked Sep 2 at 13:24









      user2520385

      1944




      1944




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          11
          down vote



          accepted










          The following does what you want:



          Apply[List, a + 2 b + 3 c, All]


          This simply applies List to all parts of the expression in one go.



          Alternatively:



          Replace[a + 2 b + 3 c, _[args___] :> args, All]
          (* a, 2, b, 3, c *)


          The idea here is to replace the head of any expression with List. Note that Replace[…,…,All] is not equivalent to ReplaceAll[…,…] (i.e. …/.…). The former replaces from the inside out, while the latter from the outside in (and ignores parts that have already been touched)



          Your attempt



          As to why your attempt doesn't work:



          • Function arguments are not variables (as in their value can't be modified). This is the reason for the "Tag … is protected" errors. To fix this, copy the value to a local variable


          • For does not localize the iteration variable, so i is shared across recursive calls. To fix this, localize i explicitly.


          • Equal/Unequal (==/!=) is for value equality, and doesn't evaluate in many cases (e.g. a==1 is not False). To do structural comparisons, use SameQ/UnsameQ (===/=!=).

          Changing only what's necessary in your code yields the following working version:



          toList[y_] := Module[
          x = y, i,
          x = List @@ x;
          For[i = 1, i <= Length[x], i++,
          If[x[[i]] =!= List @@ x[[i]],
          x[[i]] = toList[x[[i]]]
          ]
          ];
          x
          ]

          toList[a + 2 b + 3 c]
          (* a, 2 b, 3 c *)


          Further simplifications could be:




          • Replace the For loop with Do (which does localize the variable)



            toList[y_] := Module[
            x = y,
            x = List @@ x;
            Do[
            If[x[[i]] =!= List @@ x[[i]],
            x[[i]] = toList[x[[i]]]
            ],
            i, Length@x
            ];
            x
            ]



          • Replace the For/Do loop with Map (the If now needs to return something in both cases, as the output is used):



            toList[y_] := Module[
            x = y,
            x = List @@ x;
            x = Map[
            If[# =!= List @@ #,
            toList[#],
            #
            ] &,
            x
            ];
            x
            ]



          • Remove the unnecessary local variable x:



            toList[y_] := Map[
            If[# =!= List @@ #,
            toList[#],
            #
            ] &,
            List @@ y
            ]



          • Move the termination condition for the recursion into the function definition itself using Condition (/;):



            toList[y_] /; y =!= List @@ y := Map[
            toList[#] &,
            List @@ y
            ]
            toList[y_] := y



          • Use shorthands for Map (/@):



            toList[y_] /; y =!= List @@ y := toList /@ List @@ y
            toList[y_] := y



          • Remove the termination condition completely (it's not needed, as Map/Apply don't do anything on expressions that have "zero length" (i.e. atoms)



            toList[y_] := toList /@ List @@ y






          share|improve this answer




















          • Yes, it is a matter of replacement of heads.
            – Î‘λέξανδρος Ζεγγ
            Sep 2 at 14:10










          • Wow, thanks! That is a really detailed explanation
            – user2520385
            Sep 2 at 14:22

















          up vote
          3
          down vote













          expr = a + 2 b + 3 (4 E^x + 3 x);

          ReplaceRepeated[expr, f_[args___] /; (TrueQ[f =!= List]) :> List[args]]

          (* a, 2, b, 3, 4, E, x, 3, x *)





          share|improve this answer




















            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "387"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f181103%2frecursively-turn-expression-into-nested-list%23new-answer', 'question_page');

            );

            Post as a guest






























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            11
            down vote



            accepted










            The following does what you want:



            Apply[List, a + 2 b + 3 c, All]


            This simply applies List to all parts of the expression in one go.



            Alternatively:



            Replace[a + 2 b + 3 c, _[args___] :> args, All]
            (* a, 2, b, 3, c *)


            The idea here is to replace the head of any expression with List. Note that Replace[…,…,All] is not equivalent to ReplaceAll[…,…] (i.e. …/.…). The former replaces from the inside out, while the latter from the outside in (and ignores parts that have already been touched)



            Your attempt



            As to why your attempt doesn't work:



            • Function arguments are not variables (as in their value can't be modified). This is the reason for the "Tag … is protected" errors. To fix this, copy the value to a local variable


            • For does not localize the iteration variable, so i is shared across recursive calls. To fix this, localize i explicitly.


            • Equal/Unequal (==/!=) is for value equality, and doesn't evaluate in many cases (e.g. a==1 is not False). To do structural comparisons, use SameQ/UnsameQ (===/=!=).

            Changing only what's necessary in your code yields the following working version:



            toList[y_] := Module[
            x = y, i,
            x = List @@ x;
            For[i = 1, i <= Length[x], i++,
            If[x[[i]] =!= List @@ x[[i]],
            x[[i]] = toList[x[[i]]]
            ]
            ];
            x
            ]

            toList[a + 2 b + 3 c]
            (* a, 2 b, 3 c *)


            Further simplifications could be:




            • Replace the For loop with Do (which does localize the variable)



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              Do[
              If[x[[i]] =!= List @@ x[[i]],
              x[[i]] = toList[x[[i]]]
              ],
              i, Length@x
              ];
              x
              ]



            • Replace the For/Do loop with Map (the If now needs to return something in both cases, as the output is used):



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              x = Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              x
              ];
              x
              ]



            • Remove the unnecessary local variable x:



              toList[y_] := Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              List @@ y
              ]



            • Move the termination condition for the recursion into the function definition itself using Condition (/;):



              toList[y_] /; y =!= List @@ y := Map[
              toList[#] &,
              List @@ y
              ]
              toList[y_] := y



            • Use shorthands for Map (/@):



              toList[y_] /; y =!= List @@ y := toList /@ List @@ y
              toList[y_] := y



            • Remove the termination condition completely (it's not needed, as Map/Apply don't do anything on expressions that have "zero length" (i.e. atoms)



              toList[y_] := toList /@ List @@ y






            share|improve this answer




















            • Yes, it is a matter of replacement of heads.
              – Î‘λέξανδρος Ζεγγ
              Sep 2 at 14:10










            • Wow, thanks! That is a really detailed explanation
              – user2520385
              Sep 2 at 14:22














            up vote
            11
            down vote



            accepted










            The following does what you want:



            Apply[List, a + 2 b + 3 c, All]


            This simply applies List to all parts of the expression in one go.



            Alternatively:



            Replace[a + 2 b + 3 c, _[args___] :> args, All]
            (* a, 2, b, 3, c *)


            The idea here is to replace the head of any expression with List. Note that Replace[…,…,All] is not equivalent to ReplaceAll[…,…] (i.e. …/.…). The former replaces from the inside out, while the latter from the outside in (and ignores parts that have already been touched)



            Your attempt



            As to why your attempt doesn't work:



            • Function arguments are not variables (as in their value can't be modified). This is the reason for the "Tag … is protected" errors. To fix this, copy the value to a local variable


            • For does not localize the iteration variable, so i is shared across recursive calls. To fix this, localize i explicitly.


            • Equal/Unequal (==/!=) is for value equality, and doesn't evaluate in many cases (e.g. a==1 is not False). To do structural comparisons, use SameQ/UnsameQ (===/=!=).

            Changing only what's necessary in your code yields the following working version:



            toList[y_] := Module[
            x = y, i,
            x = List @@ x;
            For[i = 1, i <= Length[x], i++,
            If[x[[i]] =!= List @@ x[[i]],
            x[[i]] = toList[x[[i]]]
            ]
            ];
            x
            ]

            toList[a + 2 b + 3 c]
            (* a, 2 b, 3 c *)


            Further simplifications could be:




            • Replace the For loop with Do (which does localize the variable)



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              Do[
              If[x[[i]] =!= List @@ x[[i]],
              x[[i]] = toList[x[[i]]]
              ],
              i, Length@x
              ];
              x
              ]



            • Replace the For/Do loop with Map (the If now needs to return something in both cases, as the output is used):



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              x = Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              x
              ];
              x
              ]



            • Remove the unnecessary local variable x:



              toList[y_] := Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              List @@ y
              ]



            • Move the termination condition for the recursion into the function definition itself using Condition (/;):



              toList[y_] /; y =!= List @@ y := Map[
              toList[#] &,
              List @@ y
              ]
              toList[y_] := y



            • Use shorthands for Map (/@):



              toList[y_] /; y =!= List @@ y := toList /@ List @@ y
              toList[y_] := y



            • Remove the termination condition completely (it's not needed, as Map/Apply don't do anything on expressions that have "zero length" (i.e. atoms)



              toList[y_] := toList /@ List @@ y






            share|improve this answer




















            • Yes, it is a matter of replacement of heads.
              – Î‘λέξανδρος Ζεγγ
              Sep 2 at 14:10










            • Wow, thanks! That is a really detailed explanation
              – user2520385
              Sep 2 at 14:22












            up vote
            11
            down vote



            accepted







            up vote
            11
            down vote



            accepted






            The following does what you want:



            Apply[List, a + 2 b + 3 c, All]


            This simply applies List to all parts of the expression in one go.



            Alternatively:



            Replace[a + 2 b + 3 c, _[args___] :> args, All]
            (* a, 2, b, 3, c *)


            The idea here is to replace the head of any expression with List. Note that Replace[…,…,All] is not equivalent to ReplaceAll[…,…] (i.e. …/.…). The former replaces from the inside out, while the latter from the outside in (and ignores parts that have already been touched)



            Your attempt



            As to why your attempt doesn't work:



            • Function arguments are not variables (as in their value can't be modified). This is the reason for the "Tag … is protected" errors. To fix this, copy the value to a local variable


            • For does not localize the iteration variable, so i is shared across recursive calls. To fix this, localize i explicitly.


            • Equal/Unequal (==/!=) is for value equality, and doesn't evaluate in many cases (e.g. a==1 is not False). To do structural comparisons, use SameQ/UnsameQ (===/=!=).

            Changing only what's necessary in your code yields the following working version:



            toList[y_] := Module[
            x = y, i,
            x = List @@ x;
            For[i = 1, i <= Length[x], i++,
            If[x[[i]] =!= List @@ x[[i]],
            x[[i]] = toList[x[[i]]]
            ]
            ];
            x
            ]

            toList[a + 2 b + 3 c]
            (* a, 2 b, 3 c *)


            Further simplifications could be:




            • Replace the For loop with Do (which does localize the variable)



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              Do[
              If[x[[i]] =!= List @@ x[[i]],
              x[[i]] = toList[x[[i]]]
              ],
              i, Length@x
              ];
              x
              ]



            • Replace the For/Do loop with Map (the If now needs to return something in both cases, as the output is used):



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              x = Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              x
              ];
              x
              ]



            • Remove the unnecessary local variable x:



              toList[y_] := Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              List @@ y
              ]



            • Move the termination condition for the recursion into the function definition itself using Condition (/;):



              toList[y_] /; y =!= List @@ y := Map[
              toList[#] &,
              List @@ y
              ]
              toList[y_] := y



            • Use shorthands for Map (/@):



              toList[y_] /; y =!= List @@ y := toList /@ List @@ y
              toList[y_] := y



            • Remove the termination condition completely (it's not needed, as Map/Apply don't do anything on expressions that have "zero length" (i.e. atoms)



              toList[y_] := toList /@ List @@ y






            share|improve this answer












            The following does what you want:



            Apply[List, a + 2 b + 3 c, All]


            This simply applies List to all parts of the expression in one go.



            Alternatively:



            Replace[a + 2 b + 3 c, _[args___] :> args, All]
            (* a, 2, b, 3, c *)


            The idea here is to replace the head of any expression with List. Note that Replace[…,…,All] is not equivalent to ReplaceAll[…,…] (i.e. …/.…). The former replaces from the inside out, while the latter from the outside in (and ignores parts that have already been touched)



            Your attempt



            As to why your attempt doesn't work:



            • Function arguments are not variables (as in their value can't be modified). This is the reason for the "Tag … is protected" errors. To fix this, copy the value to a local variable


            • For does not localize the iteration variable, so i is shared across recursive calls. To fix this, localize i explicitly.


            • Equal/Unequal (==/!=) is for value equality, and doesn't evaluate in many cases (e.g. a==1 is not False). To do structural comparisons, use SameQ/UnsameQ (===/=!=).

            Changing only what's necessary in your code yields the following working version:



            toList[y_] := Module[
            x = y, i,
            x = List @@ x;
            For[i = 1, i <= Length[x], i++,
            If[x[[i]] =!= List @@ x[[i]],
            x[[i]] = toList[x[[i]]]
            ]
            ];
            x
            ]

            toList[a + 2 b + 3 c]
            (* a, 2 b, 3 c *)


            Further simplifications could be:




            • Replace the For loop with Do (which does localize the variable)



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              Do[
              If[x[[i]] =!= List @@ x[[i]],
              x[[i]] = toList[x[[i]]]
              ],
              i, Length@x
              ];
              x
              ]



            • Replace the For/Do loop with Map (the If now needs to return something in both cases, as the output is used):



              toList[y_] := Module[
              x = y,
              x = List @@ x;
              x = Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              x
              ];
              x
              ]



            • Remove the unnecessary local variable x:



              toList[y_] := Map[
              If[# =!= List @@ #,
              toList[#],
              #
              ] &,
              List @@ y
              ]



            • Move the termination condition for the recursion into the function definition itself using Condition (/;):



              toList[y_] /; y =!= List @@ y := Map[
              toList[#] &,
              List @@ y
              ]
              toList[y_] := y



            • Use shorthands for Map (/@):



              toList[y_] /; y =!= List @@ y := toList /@ List @@ y
              toList[y_] := y



            • Remove the termination condition completely (it's not needed, as Map/Apply don't do anything on expressions that have "zero length" (i.e. atoms)



              toList[y_] := toList /@ List @@ y







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 2 at 14:06









            Lukas Lang

            5,1531525




            5,1531525











            • Yes, it is a matter of replacement of heads.
              – Î‘λέξανδρος Ζεγγ
              Sep 2 at 14:10










            • Wow, thanks! That is a really detailed explanation
              – user2520385
              Sep 2 at 14:22
















            • Yes, it is a matter of replacement of heads.
              – Î‘λέξανδρος Ζεγγ
              Sep 2 at 14:10










            • Wow, thanks! That is a really detailed explanation
              – user2520385
              Sep 2 at 14:22















            Yes, it is a matter of replacement of heads.
            – Î‘λέξανδρος Ζεγγ
            Sep 2 at 14:10




            Yes, it is a matter of replacement of heads.
            – Î‘λέξανδρος Ζεγγ
            Sep 2 at 14:10












            Wow, thanks! That is a really detailed explanation
            – user2520385
            Sep 2 at 14:22




            Wow, thanks! That is a really detailed explanation
            – user2520385
            Sep 2 at 14:22










            up vote
            3
            down vote













            expr = a + 2 b + 3 (4 E^x + 3 x);

            ReplaceRepeated[expr, f_[args___] /; (TrueQ[f =!= List]) :> List[args]]

            (* a, 2, b, 3, 4, E, x, 3, x *)





            share|improve this answer
























              up vote
              3
              down vote













              expr = a + 2 b + 3 (4 E^x + 3 x);

              ReplaceRepeated[expr, f_[args___] /; (TrueQ[f =!= List]) :> List[args]]

              (* a, 2, b, 3, 4, E, x, 3, x *)





              share|improve this answer






















                up vote
                3
                down vote










                up vote
                3
                down vote









                expr = a + 2 b + 3 (4 E^x + 3 x);

                ReplaceRepeated[expr, f_[args___] /; (TrueQ[f =!= List]) :> List[args]]

                (* a, 2, b, 3, 4, E, x, 3, x *)





                share|improve this answer












                expr = a + 2 b + 3 (4 E^x + 3 x);

                ReplaceRepeated[expr, f_[args___] /; (TrueQ[f =!= List]) :> List[args]]

                (* a, 2, b, 3, 4, E, x, 3, x *)






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Sep 2 at 13:49









                Anton Antonov

                21.5k164107




                21.5k164107



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f181103%2frecursively-turn-expression-into-nested-list%23new-answer', 'question_page');

                    );

                    Post as a guest













































































                    Comments

                    Popular posts from this blog

                    What does second last employer means? [closed]

                    List of Gilmore Girls characters

                    Confectionery