Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
add comment

3 Answers 3

up vote 10 down vote accepted

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}} *)
share|improve this answer
    
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}}} –  Morry Aug 18 '13 at 19:42
add comment

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}}
share|improve this answer
add comment

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}}

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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