15
$\begingroup$

Given this input

lst1 = {{a, b, c}, {d, e, f}};
lst2 = {1, 2};

and the goal is to generate this output

{  {{1, a}, {1, b}, {1, c}}, 
   {{2, d}, {2, e}, {2, f}}
}

Perfect candidate for MapThread So I made this diagram first to figure what the function I want to map should be

enter image description here

So the function to use inside MapThread, needs to also use Map itself (in order to map each item into the other list). So I came up with this:

lst1 = {{a, b, c}, {d, e, f}};
lst2 = {1, 2};
foo[i_, lst_List] := List[i, #] & /@ lst
MapThread[foo[#1, #2] &, {Range[Length@lst2], lst1}]
(*  {  {{1,a}, {1,b}, {1,c}},       {{2,d}, {2,e}, {2,f}}   }  *)

Now here is the question: Is there a way to do the above without having to define an explicit function but using pure function inside MapThread?

I was getting conflict with # mapping. This is sort of the thing I was trying to do, but can't get the syntax right

(*invalid, for illustration only *)
MapThread[ 
 Function[{idx, lst},List[idx, #] & /@ lst] &  ?? ??    ,{Range[Length@lst2],lst1}]

Or if you know of a better approach to do this, that will be fine as well.

$\endgroup$
2
  • $\begingroup$ Get rid of that last & in your illustration as you already have the long form of using Function[ ]. You can also use Thread[{##}] & as the function for MapThread $\endgroup$
    – ssch
    Nov 29, 2013 at 18:38
  • $\begingroup$ Thanks, I guess I was close :) can you show how to use {##}? I am not good with ##, I know # only now. $\endgroup$
    – Nasser
    Nov 29, 2013 at 18:46

8 Answers 8

11
$\begingroup$
MapThread[Thread[{##}] &, {lst2, lst1}] 

Map[Thread, {lst2, lst1}\[Transpose]]

## is used so Thread gets called like Thread[{1, {a, b, c}}] As MapThread gives two arguments in this case it is equivalent to Thread[{#1, #2}]& and Composition[Thread, List]

$\endgroup$
2
  • 1
    $\begingroup$ Thread[{##}] is nice since it is shorter. I have to read about it, as never saw it before. $\endgroup$
    – Nasser
    Nov 29, 2013 at 18:51
  • 2
    $\begingroup$ V10 style: MapThread[Thread@*List, {lst2, lst1}] $\endgroup$
    – Kuba
    Apr 18, 2016 at 8:30
8
$\begingroup$

Very similar to ssch's second answer, but sometimes Thread feels more natural than Transpose:

Thread /@ Thread @ {lst2, lst1}

Less clear, but more interesting, is to make a Listable version of List:

Function[, {##}, Listable][lst2, lst1]

You could also use my smartThread function:

smartThread @ {lst2, lst1}
$\endgroup$
1
  • 1
    $\begingroup$ smartThread is so cool. I did not know about it, will start using it. I wish Mathematica had such functions build in. I am starting to think the we need a major overhaul of number of Mathematica core functions to add more options to them and make them more flexible. Sometimes I feel it takes too much work and skill to do some basic manipulation of lists. $\endgroup$
    – Nasser
    Nov 29, 2013 at 23:20
6
$\begingroup$

A Map/MapThread-less solution

Transpose@Inner[List, lst2, lst1, List]
$\endgroup$
4
$\begingroup$

An Outer version:

Flatten[ MapThread[ Outer[List, {#1}, #2] &, {lst2, lst1}], 1]

{{{1, a}, {1, b}, {1, c}}, {{2, d}, {2, e}, {2, f}}}

$\endgroup$
4
$\begingroup$
MapThread[Function[{u, b}, List[b, #] & /@ u], {lst1, lst2}];

and the reverse example with Slots on top:

MapThread[Map[Function[u, {#2, u}], #] &, {lst1, lst2}]
{{{1, a}, {1, b}, {1, c}}, {{2, d}, {2, e}, {2, f}}}

Approach with MapIndexed:

MapIndexed[{lst2[[#2[[1]]]], #} &, lst1, {2}]
$\endgroup$
3
$\begingroup$
MapThread[With[{n = #2}, {n, #} & /@ #1] &, {lst1, lst2}]

{{{ 1, a}, {1, b}, {1, c}}, {{2, d}, {2, e}, {2, f}}}

$\endgroup$
3
$\begingroup$

Why MapThread?

While both MapThread and in particular MapIndexed are slow, using some Transpose based constructions, one can take Map (or even ParallelMap, if appropriate):

Map[Function[v, Map[{v[[2]], #} &, v[[1]]]][#] &, Transpose[Join[{lst1, lst2}]]]

Edit: I suddenly noticed that cascading Map was a stupid idea, so here my correction:

Map[
 Function[v, Transpose@{ConstantArray[v[[2]], Length[v[[1]]]], v[[1]]}
 ][#] &, Transpose[Join[{lst1, lst2}]]
]

In particular for large lists as usually can occur in image analysis, trying to avoid MapThread and MapIndexed is often recommended.

$\endgroup$
1
$\begingroup$

Using Table,

Thread /@ Table[{lst2[[k]], lst1[[k]]}, {k, Length[lst1]}]

{{{1, a}, {1, b}, {1, c}}, {{2, d}, {2, e}, {2, f}}}

$\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.