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.

How would you, given a list {1, 2, 3, 4}, apply a function f to 1 and 2, then 2 and 3, etc.?

{f[1,2], f[2,3], f[3,4]}

More generally, how do you define which parts of a list you want to pass/Map/Apply to a function that takes multiple arguments?

share|improve this question
    
Thank you and a big thanks to everyone who contributed alternative solutions as well. –  Teo Sartori Apr 9 '12 at 20:28

6 Answers 6

up vote 6 down vote accepted

You might first partition your list and then use Map as usual :

f[#[[1]], #[[2]]] & /@ Partition[{1,2,3,4}, 2, 1]

(* {f[1, 2], f[2, 3], f[3, 4]} *)
share|improve this answer
    
Excellent, that works. –  Teo Sartori Apr 9 '12 at 14:43
    
why is it f[#[[1]], #[[2]]] and not just f[#1,#2]? –  Eiyrioü von Kauyf Apr 10 '12 at 0:58
2  
f[#1, #2] & @@@ Partition[{1,2,3}, 2, 1] –  Paxinum Apr 10 '12 at 7:40

You can use

f @@@ Partition[{1,2,3,4}, 2, 1]

which will give

{f[1,2], f[2,3], f[3,4]}
share|improve this answer
    
And this one is nice and short. –  Teo Sartori Apr 9 '12 at 14:44

Several additional alternatives:

MapThread:

     MapThread[g, #] &@{Most@#, Rest@#} &@{r, s, t, u, v, w}
     (*  ==>  {g[r, s], g[s, t], g[t, u], g[u, v], g[v, w]} *)

or,

    MapThread[g, #] &@Transpose@Partition[#, 2,1] &@{r, s, t, u, v, w}
    (* ==> {g[r, s], g[s, t], g[t, u], g[u, v], g[v, w]} *)

which allows more flexibility to specify the lists to thread over, like:

   MapThread[g, #] &@Transpose@Partition[#, 3, 2, 1] &@{r, s, t, u, v, w}
   (* ==>  {g[r, s, t], g[s, t, u], g[t, u, v], g[u, v, w]} *)

Inner: with last argument set to List gives the same result as MapThread:

   Inner[g, Sequence @@ #, List] &@Transpose@Partition[#, 2, 1] &@{r, s,t, u, v, w}
   (* ==> {g[r, s], g[s, t], g[t, u], g[u, v], g[v, w]} *)

Thread:

     Thread[g[Most@#, Rest@#]] &@{r, s, t, u, v, w};
     Thread[g[Sequence @@ #]] &@({Most@#, Rest@#} &@{r, s, t, u, v, w});
     Thread[g[Sequence @@ #]] &@(Transpose@Partition[#, 2, 1] &@{r, s, t,u, v, w});

From docs on Thread:

Functions with attribute Listable are threaded automatically over lists.

Hence for Listable functions, e.g., for h in the following example:

 SetAtrributes[h, Listable];
 h[Sequence @@ #] &@(Transpose@Partition[#, 2, 1] &@{r, s, t, u, v, w})

gives the same result as does

Thread[h[Sequence @@ #]] &@(Transpose@Partition[#, 2, 1] &@{r, s, t, u, v, w}).

Also from docs:

MapThread takes the function and its arguments separately.

Thread evaluates the whole expression before threading.

Hence, using MapThread is "safer" as pointed out in Mr.Wizard's comments.

Timings:

Test data:

    tsts = Table[RandomInteger[1000, 1000000], {10}];

Results table (apologies for not figuring out how to apply Thread in the following):

    Grid[{{"method", "timing"}, 
    {HoldForm[Thread[g[Sequence @@ #]] &@(Transpose@Partition[#, 2, 1] &)], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    Thread[g[Sequence @@ #]] &@ (Transpose@Partition[#, 2, 1] &@ tsts[[i]])][[1]], {i, 1, 10}] // Mean},
    {HoldForm[Thread[g[Most@#, Rest@#]] &], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    Thread[g[Most@#, Rest@#]] &@tsts[[i]]][[1]], {i, 1, 10}] //  Mean},
    {HoldForm[MapThread[g, Transpose@Partition[#, 2, 1]] &], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    MapThread[g, Transpose@Partition[#, 2, 1]] &@tsts[[i]]][[1]], {i, 1, 10}] // Mean},
    {HoldForm[MapThread[g, {Most@#, Rest@#}] &], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    MapThread[g, {Most@#, Rest@#}] &@tsts[[i]]][[1]], {i, 1, 10}] //  Mean},
    {HoldForm[Inner[g, Sequence @@ #, List] &@{Most@#, Rest@#} &], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    Inner[g,Sequence @@ #,List] &@{Most@#,Rest@#} &@tsts[[i]]][[1]], {i, 1, 10}] // Mean}, 
    {HoldForm[Inner[g, Sequence @@ #, List] &@Transpose@Partition[#, 2, 1] &], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    Inner[g, Sequence @@ #, List] &@Transpose@Partition[#, 2, 1] &@
    tsts[[i]]][[1]], {i, 1, 10}] // Mean},
    {HoldForm[Developer`PartitionMap[g @@ # &, tsts[[i]], 2, 1]], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    Developer`PartitionMap[g @@ # &, tsts[[i]], 2, 1]][[1]], {i, 1, 10}] // Mean}, 
    {HoldForm[g @@@ Partition[tsts[[i]], 2, 1]], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    g @@@ Partition[tsts[[i]], 2, 1]][[1]], {i, 1, 10}] // Mean}, 
    {HoldForm[ g @@@ Most[{tsts[[i]], RotateLeft@tsts[[i]]}\[Transpose]]], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
    g @@@ Most[{tsts[[i]], RotateLeft@tsts[[i]]}\[Transpose]]][[1]], {i, 1, 10}] // 
Mean}, 
    {HoldForm[Fold[(Sow[g[#1, #2]]; #2) &, First@#, Rest@#] &@tsts[[i]]; // 
     Reap // Last], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
     Fold[(Sow[g[#1, #2]]; #2) &, First@#, Rest@#] &@tsts[[i]]; //
      Reap // Last][[1]], {i, 1, 10}] // Mean},
    {HoldForm[g[#[[1]], #[[2]]] & /@ Partition[tsts[[i]], 2, 1]], 
    Table[AbsoluteTiming[ClearSystemCache[]; 
     g[#[[1]], #[[2]]] & /@ Partition[tsts[[i]], 2, 1]][[1]], {i, 1,
     10}] // Mean}}, 
    Frame -> All]

Timing results:

enter image description here

share|improve this answer
    
Probably too specific since the OP was asking "generally" but if you expand this answer to address Listable functions and discuss the performance benefits you'll heartily earn my +1. –  Mr.Wizard Apr 9 '12 at 15:03
    
@Mr.Wizard I like this one, and it's the type of thing I often use as I didn't know about Developer`Partition until very recently. –  rcollyer Apr 9 '12 at 15:11
    
@rcollyer I like this one a lot too (hence: "heartily") but the answer is unfinished. Thread as shown is dangerous because of evaluation order, and the most elegant an efficient possibility (with Listable functions) is neither shown nor explained. –  Mr.Wizard Apr 9 '12 at 15:13
    
@Mr.Wizard How is Thread dangerous? I don't see it. I also, don't see the answer as being incomplete. Instead, I see it as not being generalizable, e.g. what if the OP wanted to expand it to sequential, overlapping triples, instead? –  rcollyer Apr 9 '12 at 15:20
    
@rcollyer so f = Print; Thread[f[Most@#, Rest@#]] &@{1, 2, 3} does what you expect and desire? I say incomplete because the prime advantage to this method is performance, especially with Listable functions. If kguler doesn't add that, I will. –  Mr.Wizard Apr 9 '12 at 15:36

I would probably use Developer`PartitionMap, but here's an approach using Fold, Reap and Sow just to demonstrate the various ways of doing the same thing:

list = {1, 2, 3, 4};
Fold[(Sow[f[#1, #2]]; #2) &, First@#, Rest@#] &@ list; // Reap // Last
(* Out[1]= {{f[1, 2], f[2, 3], f[3, 4]}} *)
share|improve this answer

And yet another one:

list = Range[5];

f @@@ Most[{list, RotateLeft@list}\[Transpose]]

(*
==> {f[1, 2], f[2, 3], f[3, 4], f[4, 5]}
*)
share|improve this answer

If the arguments are sequential there is a function Developer`PartitionMap that does this directly, potentially saving considerable memory over Partition.

Developer`PartitionMap[f @@ # &, Range@5, 2, 1]
{f[1, 2], f[2, 3], f[3, 4], f[4, 5]}

Syntax is the same as for Partition but with the function to map inserted as the first argument. Notice in my use above that I needed Apply (short form @@) to pass the elements as arguments rather than a single list.

If the arguments are not sequental you can use Part:

list = {a, b, c, d, e}; 

parts = {{1, 2}, {4, 1, 3}, {5, 2}};

f @@ list[[#]] & /@ parts
{f[a, b], f[d, a, c], f[e, b]}
share|improve this answer

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.