12
$\begingroup$

I have two lists of the same length, the first one a list of integers, and the second one a list of arbitrary-length lists of integers. I would like to make a list of 2-element lists, of all possible pairs of an element from the first list, followed by any of the elements of the list in the corresponding position in the second list. For example. given

{1,2,3}

and

{{x},{y1,y2},{z}}

I would like to construct

{{1,x},{2,y1},{2,y2},{3,z}}

In fact, the first list will always be of the form {1,2,...,n}.

I've tried many combinations of Inner, Outer, Map, Thread, MapThread, Flatten and other commands, and still haven't succeeded,

$\endgroup$

7 Answers 7

14
$\begingroup$
L1 = {1, 2, 3};
L2 = {{x}, {y1, y2}, {z}};
Flatten[Thread /@ Transpose @ {L1, L2}, 1]

{{1, x}, {2, y1}, {2, y2}, {3, z}}

replacing Flatten with Join looks a bit nicer (tip of the hat to @HenrikSchumacher):

Join @@ Thread /@ Transpose @ {L1, L2}

And if you assume that L1 == Range[Length[L2]] as specified, then you could also do this (tip of the hat to @MikeY):

Reverse /@ Flatten[MapIndexed[Outer[List, ##] &, L2], 2]
$\endgroup$
9
$\begingroup$

Alternatively:

L1 = {1, 2, 3};
L2 = {{x}, {y1, y2}, {z}};
Module[{tmp = L2}, tmp[[All, All]] = L1;
 Flatten[{tmp, L2}, {{2, 3}, {1}}]]

{{1, x}, {2, y1}, {2, y2}, {3, z}}

$\endgroup$
8
$\begingroup$
L1 = {1, 2, 3};
L2 = {{x}, {y1, y2}, {z}};
Join @@ MapThread[Thread[{#1, #2}] &, {L1, L2}]

{{1, x}, {2, y1}, {2, y2}, {3, z}}

$\endgroup$
7
$\begingroup$

The process can also be viewed as a kind of inner product:

L1 = {1, 2, 3};
L2 = {{x}, {y1, y2}, {z}};
Flatten[Thread /@ Inner[List, L1, L2, List], 1]
{{1, x}, {2, y1}, {2, y2}, {3, z}}
$\endgroup$
5
$\begingroup$

I just did this in this problem...

https://mathematica.stackexchange.com/a/191396/47314

Version tailored for you, using MapIndexed[] since L1 will always correspond to L2 in length.

L2 = {{xx}, {y1, y2}, {z}};
Partition[Flatten@MapIndexed[Outer[{#1, #2} &, #2, #1] &, L2, 1], 2]
(* {{1, xx}, {2, y1}, {2, y2}, {3, z}} *)
$\endgroup$
2
$\begingroup$
list = {{x}, {y1, y2}, {z}};

Using MapIndexed with a level specification of {2}

Catenate @ MapIndexed[{#2[[1]], #1} &, list, {2}]

{{1, x}, {2, y1}, {2, y2}, {3, z}}

$\endgroup$
2
$\begingroup$

Some variations:

Clear["Global`*"];

L1 = {1, 2, 3};
L2 = {{x}, {y1, y2}, {z}};

Inner[Thread@*List, L1, L2, Join]

or

Flatten[{L1, L2}, {{2}, {1}}] // Map[Thread] // Map[Apply[Sequence]]

{{1, x}, {2, y1}, {2, y2}, {3, z}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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