3

How can the following list can be decomposed into separate two coordinate lists?

list = {{1, {0}}, {2, {0}}, {3, {-2, 0, 2}}, {4, {-2, 0, 2}}, {5, {-2, 0, 2}}};

what I wish to obtain is

list1 = {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}};
list2 = {{3, -2}, {4, -2}, {5, -2}};
list3 = {{3, 2}, {4, 2}, {5, 2}};

or

list1 = {{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}};
list2 = {{1, 0}, {2, 0}, {3, -2}, {4, -2},{5, -2}};
list3 = {{1, 0}, {2, 0}, {3, 2}, {4, 2}, {5, 2}};

or

list1 = {{1, 0}, {2, 0}, {3, -2}, {4, -2}, {5, -2}};
list2 = {{3, 0}, {4, 0}, {5, 0}};
list3 = {{3, 2}, {4, 2}, {5, 2}};
jarhead
  • 2,065
  • 12
  • 19
  • can you specify the rule for the list composition? – Fraccalo Feb 16 '20 at 14:30
  • @Fraccalo, consider this as an example for an output of a pitchfork bifurcation solution, it's not that relevant though. – jarhead Feb 16 '20 at 14:32
  • well, the point is that the three lists seem quite different, one can write ad hoc codes for obtaining one of them, but such codes wouldn't be general – Fraccalo Feb 16 '20 at 14:36
  • @Fraccalo, the idea is that each list is decomposed from the first,second, or third element of the second sublist. I gave several examples for an output that can separate them to have three lines that can be plotted in a graph. – jarhead Feb 16 '20 at 14:39
  • @jarhead Your second set of lists does not make sense to me when compared with the other two. Can you confirm that Set-2 is a desired outcome and not (say) {{{1, 0}, {2, 0}, {3, 2}, {4, 2}, {5, 2}}, {{3, -2}, {4, -2}, {5, -2}}, {{3, 0}, {4, 0}, {5, 0}}} (and there are other possibilities)? @march has given a very nice solution based on a ragged Transpose which is adaptable to Set-1 but (it seems to me) not Set-2 – user1066 Feb 16 '20 at 20:32

5 Answers5

3

Implement a ragged transpose after turning each sublist into a list of pairs, like so:

list = {{1, {0}}, {2, {0}}, {3, {-2, 0, 2}}, {4, {-2, 0, 2}}, {5, {-2,0, 2}}};
Flatten[Thread /@ list, {2}]
(* {{{1, 0}, {2, 0}, {3, -2}, {4, -2}, {5, -2}},
    {{3, 0}, {4, 0}, {5, 0}},
    {{3, 2}, {4, 2}, {5, 2}}} *)

If you really want to name these sublists, you can do

Clear[list1, list2, list3]
{list1, list2, list3} = Flatten[Thread /@ list, {2}];
march
  • 23,399
  • 2
  • 44
  • 100
3
List@@Flatten/@ (list /. {a_, {b_, 0, d_}} -> { a, 0} )
List@@Flatten/@ (list /. {a_, {b_, 0, d_}} -> { a, b} )
List@@Flatten/@ (list /. {a_, {b_, 0, d_}} -> { a, d} )
Alucard
  • 2,639
  • 13
  • 22
2

The first list:

listsa = GatherBy[Join @@ (Thread /@ list), Last];
Column[listsa]

enter image description here

The second list:

listsb1 = Join @@@ 
   GatherBy[Thread[Thread /@ list, List, {3, 5}] /. {{a_, b_}} :> {a, b}, #[[-1, -1]] &];

or

listsb2 = TemporalData[Transpose@PadLeft[#[[All, -1]]], {#[[All, 1]]}]["Paths"] &@list;

listsb1 == listsb2

True

Column[listsb1]

enter image description here

The third:

listsc = Join[##, 2] & @@ Map[List, Thread /@ list, {-2}];
Column[listsc]

enter image description here

kglr
  • 394,356
  • 18
  • 477
  • 896
1

It's still not fully clear what are you exactly looking for, but this is a piece of code that might help you (it gives you the first set of lists you give in your question). It can easily be readapted for the other cases:

list = {{1, {0}}, {2, {0}}, {3, {-2, 0, 2}}, {4, {-2, 0, 2}}, {5, {-2,0, 2}}};

ind = DeleteDuplicates@Flatten[list[[;; , 2]]]

{0, -2, 2}

{list1, list2, list3} =  Cases[list, {a_, b_} /; MemberQ[b, #] -> {a, #}] & /@ ind

{{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}, {{3, -2}, {4, -2}, {5, -2}}, {{3, 2}, {4, 2}, {5, 2}}}

Fraccalo
  • 6,057
  • 13
  • 28
1

Adapting the answer given by @march, where the second argument of Flatten is used to transpose a ragged array (see this answer):

Set-1 may be generated as follows:

{list1a, list2a, list3a}=Distribute[#, List]&/@(list /.{x_,y_,z_}:> {y,x,z})//Flatten[#,{{2}}]&

list1a
list2a
list3a

{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}

{{3, -2}, {4, -2}, {5, -2}}

{{3, 2}, {4, 2}, {5, 2}}

Set 3 (as per @march answer)

{list3a, list3b, list3c}=Distribute[#, List]&/@list//Flatten[#,{{2}}]&

{{1, 0}, {2, 0}, {3, -2}, {4, -2}, {5, -2}}

{{3, 0}, {4, 0}, {5, 0}}

{{3, 2}, {4, 2}, {5, 2}}

Set-2

As given by the OP the lists may be obtained as follows (in this case a simple Transpose is all that is required):

{list1b, list2b,list3b}=Distribute[#, List]&/@(list /.{x_,y_,z_}:> {y,x,z}/.{0}:> {0,0,0})//Transpose

{{1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}}

{{1, 0}, {2, 0}, {3, -2}, {4, -2}, {5, -2}}

{{1, 0}, {2, 0}, {3, 2}, {4, 2}, {5, 2}}

But perhaps the OP requires something like the following?

{list1x, list2x,list3x}=Distribute[#, List]&/@(list /.{x_,y_,z_}:> {z,x,y})//Flatten[#,{{2}}]&

{{1, 0}, {2, 0}, {3, 2}, {4, 2}, {5, 2}}

{{3, -2}, {4, -2}, {5, -2}}

{{3, 0}, {4, 0}, {5, 0}}

Comment

In all cases, (as shown in the @march answer), Thread may be substituted for Distribute

(Distribute[#, List]&/@(list /.{x_,y_,z_}:> {y,x,z})//Flatten[#,{2}]&)===(Thread/@(list /.{x_,y_,z_}:> {y,x,z})//Flatten[#,{2}]&)
user1066
  • 17,923
  • 3
  • 31
  • 49