8
$\begingroup$

I have a series of lists in the form below:

list={ {1,1} , {2,2}, {3,{3,1},{3,2},{31,{31,1},{32,2}}} }

Its a nested list which the dimension is changing case to case. I want to manipulate the list to have an output like this:

LIST={{1,1},{2,2},{3,3,1},{3,3,2},{3,31,31,1},{3,31,32,2}}

I am trying to use this ReplaceList rule

list //. {a_, {b___}} :> {a, b}

But it is not working at all!! How should I make a list out of this nested list?

$\endgroup$
10
$\begingroup$

The problem: your pattern, {a_, {b___}} will only match a list with exactly two elements, the second of which has to be a list. As you can see, there is no such list anywhere in your expression, which is why it doesn't work.

You can correct it as follows:

sol = list //. {h__Integer, t__List} :> Map[{h} ~Join~ # &, {t}]
(* {{1, 1}, {2, 2}, {{3, 3, 1}, {3, 3, 2}, {{3, 31, 31, 1}, {3, 31, 32, 2}}}} *)

Note that the lists have the correct elements, but are nested. You can again employ rules to "flatten" them out with:

FixedPoint[Replace[#, {x__List} :> x, {1, Infinity}] &, sol]
(* {{1, 1}, {2, 2}, {3, 3, 1}, {3, 3, 2}, {3, 31, 31, 1}, {3, 31, 32, 2}} *)
$\endgroup$
  • $\begingroup$ How to get ride of the nests to a certain level? I mean to get a result like this {{1,1},{2,2},{3,3,1},{3,3,2},{3,31,{31,1}},{3,31,{32,2}}} $\endgroup$ – Morry Aug 18 '13 at 19:42
4
$\begingroup$

ReplaceRepeated (short form //.) uses a depth-first preorder traversal. As an alternative you might consider using a depth-first postorder traversal, as provided by MapAll (short form //@).

Because rm -rf's code goes in the top-down direction he used matching and prepending of multiple integers at once. Half way through the process the list is transformed into this:

{{1, 1}, {2, 2}, {{3, 3, 1}, {3, 3, 2}, {3, 31, {31, 1}, {32, 2}}}}

This may or may not have been your intention. For example, his method will expand {0, 1, {2, 2}, {3, 3}} into {{0, 1, 2, 2}, {0, 1, 3, 3}}. Suppose you didn't want this, and wanted to expand only list starting with a single atom rather than a sequence?

You might then use something like this:

f[{a_?AtomQ, b__List}] := Sequence @@ (Prepend[#, a] & /@ {b})
f[other_] := other

f //@ list
{{1, 1}, {2, 2}, {3, 3, 1}, {3, 3, 2}, {3, 31, 31, 1}, {3, 31, 32, 2}}

And:

list2 = {{1, 1}, {0, 1, {2, 2}}, {3, {3, 1}, {3, 2}, {31, {31, 1}, {32, 2}}}};

f //@ list2
{{1, 1}, {0, 1, {2, 2}}, {3, 3, 1}, {3, 3, 2}, {3, 31, 31, 1}, {3, 31, 32, 2}}
$\endgroup$
2
$\begingroup$

Also:

list = {{1, 1}, {2, 2}, {3, {3, 1}, {3, 2}, {31, {31, 1}, {32, 2}}}};

Cases[Level[list //. {x___Integer, a_Integer,  b__List} :> {x, (Prepend[#, a] & /@ {b})}, Infinity], 
     {__Integer}, {1}]

{{1, 1}, {2, 2}, {3, 3, 1}, {3, 3, 2}, {3, 31, 31, 1}, {3, 31, 32, 2}}

$\endgroup$

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.