Recursively turn expression into nested list

Clash 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?
list-manipulation simplifying-expressions
add a comment |Â
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?
list-manipulation simplifying-expressions
add a comment |Â
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?
list-manipulation simplifying-expressions
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?
list-manipulation simplifying-expressions
edited Sep 2 at 13:29
asked Sep 2 at 13:24
user2520385
1944
1944
add a comment |Â
add a comment |Â
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
Fordoes not localize the iteration variable, soiis shared across recursive calls. To fix this, localizeiexplicitly.Equal/Unequal(==/!=) is for value equality, and doesn't evaluate in many cases (e.g.a==1is notFalse). To do structural comparisons, useSameQ/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
Forloop withDo(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/Doloop withMap(theIfnow 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_] := yUse shorthands for
Map(/@):toList[y_] /; y =!= List @@ y := toList /@ List @@ y
toList[y_] := yRemove the termination condition completely (it's not needed, as
Map/Applydon't do anything on expressions that have "zero length" (i.e. atoms)toList[y_] := toList /@ List @@ y
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
add a comment |Â
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 *)
add a comment |Â
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
Fordoes not localize the iteration variable, soiis shared across recursive calls. To fix this, localizeiexplicitly.Equal/Unequal(==/!=) is for value equality, and doesn't evaluate in many cases (e.g.a==1is notFalse). To do structural comparisons, useSameQ/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
Forloop withDo(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/Doloop withMap(theIfnow 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_] := yUse shorthands for
Map(/@):toList[y_] /; y =!= List @@ y := toList /@ List @@ y
toList[y_] := yRemove the termination condition completely (it's not needed, as
Map/Applydon't do anything on expressions that have "zero length" (i.e. atoms)toList[y_] := toList /@ List @@ y
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
add a comment |Â
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
Fordoes not localize the iteration variable, soiis shared across recursive calls. To fix this, localizeiexplicitly.Equal/Unequal(==/!=) is for value equality, and doesn't evaluate in many cases (e.g.a==1is notFalse). To do structural comparisons, useSameQ/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
Forloop withDo(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/Doloop withMap(theIfnow 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_] := yUse shorthands for
Map(/@):toList[y_] /; y =!= List @@ y := toList /@ List @@ y
toList[y_] := yRemove the termination condition completely (it's not needed, as
Map/Applydon't do anything on expressions that have "zero length" (i.e. atoms)toList[y_] := toList /@ List @@ y
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
add a comment |Â
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
Fordoes not localize the iteration variable, soiis shared across recursive calls. To fix this, localizeiexplicitly.Equal/Unequal(==/!=) is for value equality, and doesn't evaluate in many cases (e.g.a==1is notFalse). To do structural comparisons, useSameQ/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
Forloop withDo(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/Doloop withMap(theIfnow 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_] := yUse shorthands for
Map(/@):toList[y_] /; y =!= List @@ y := toList /@ List @@ y
toList[y_] := yRemove the termination condition completely (it's not needed, as
Map/Applydon't do anything on expressions that have "zero length" (i.e. atoms)toList[y_] := toList /@ List @@ y
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
Fordoes not localize the iteration variable, soiis shared across recursive calls. To fix this, localizeiexplicitly.Equal/Unequal(==/!=) is for value equality, and doesn't evaluate in many cases (e.g.a==1is notFalse). To do structural comparisons, useSameQ/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
Forloop withDo(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/Doloop withMap(theIfnow 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_] := yUse shorthands for
Map(/@):toList[y_] /; y =!= List @@ y := toList /@ List @@ y
toList[y_] := yRemove the termination condition completely (it's not needed, as
Map/Applydon't do anything on expressions that have "zero length" (i.e. atoms)toList[y_] := toList /@ List @@ y
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
add a comment |Â
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
add a comment |Â
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 *)
add a comment |Â
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 *)
add a comment |Â
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 *)
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 *)
answered Sep 2 at 13:49
Anton Antonov
21.5k164107
21.5k164107
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
