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
For
does not localize the iteration variable, soi
is shared across recursive calls. To fix this, localizei
explicitly.Equal
/Unequal
(==
/!=
) is for value equality, and doesn't evaluate in many cases (e.g.a==1
is 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
For
loop 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
/Do
loop withMap
(theIf
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_] := 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
/Apply
don'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
For
does not localize the iteration variable, soi
is shared across recursive calls. To fix this, localizei
explicitly.Equal
/Unequal
(==
/!=
) is for value equality, and doesn't evaluate in many cases (e.g.a==1
is 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
For
loop 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
/Do
loop withMap
(theIf
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_] := 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
/Apply
don'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
For
does not localize the iteration variable, soi
is shared across recursive calls. To fix this, localizei
explicitly.Equal
/Unequal
(==
/!=
) is for value equality, and doesn't evaluate in many cases (e.g.a==1
is 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
For
loop 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
/Do
loop withMap
(theIf
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_] := 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
/Apply
don'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
For
does not localize the iteration variable, soi
is shared across recursive calls. To fix this, localizei
explicitly.Equal
/Unequal
(==
/!=
) is for value equality, and doesn't evaluate in many cases (e.g.a==1
is 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
For
loop 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
/Do
loop withMap
(theIf
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_] := 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
/Apply
don'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
For
does not localize the iteration variable, soi
is shared across recursive calls. To fix this, localizei
explicitly.Equal
/Unequal
(==
/!=
) is for value equality, and doesn't evaluate in many cases (e.g.a==1
is 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
For
loop 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
/Do
loop withMap
(theIf
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_] := 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
/Apply
don'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