8
$\begingroup$

I know that

F /@ {a,b,c,d,e,f}

produces

{F[a],F[b],F[c],F[d],F[e],F[f]}

It can also be rewritten as

F @@@ Partition[{a,b,c,d,e,f},1]

Question

If I want to produce

{F[a,b],F[c,d],F[e,f]}

for the same list

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

is there any other simpler ways than the following?

F @@@ Partition[{a,b,c,d,e,f},2]
$\endgroup$
5
  • $\begingroup$ And what is wrong with F @@@ Partition[{a,b,c,d,e,f},2] ? which kind of features are you looking for in a different solution? $\endgroup$
    – rhermans
    Jul 28, 2018 at 12:36
  • 1
    $\begingroup$ @rhermans: I am looking for the built-in function if any. $\endgroup$
    – D G
    Jul 28, 2018 at 12:38
  • 2
    $\begingroup$ Developer`PartitionMap $\endgroup$
    – rcollyer
    Jul 28, 2018 at 12:43
  • $\begingroup$ Maybe Partition[data, 2, 2, {1, -1}, 0, F] $\endgroup$
    – Coolwater
    Jul 28, 2018 at 19:33
  • 1
    $\begingroup$ @Coolwater: Without Partition rather than with Partition. Make it shorter rather than make it longer. $\endgroup$
    – D G
    Jul 28, 2018 at 23:23

1 Answer 1

8
$\begingroup$

BlockMap and Developer`PartitionMap do pretty the same thing in this case and they are roughly of same speed.

data = RandomReal[{-1, 1}, {1000000}];
F = Sin[#1 - #2] &;
a = BlockMap[F @@ # &, data, 2]; // RepeatedTiming // First
b = Developer`PartitionMap[F @@ # &, data, 2]; // RepeatedTiming // First
a === b

0.94367

0.927

True

This is however not as fast as your original version:

a1 = F @@@ Partition[data, 2]; // RepeatedTiming // First
a === a1

0.58

True

It may be also worthwhile to replace F by a function G with vector argument, because this circumvents Apply.

G = Sin[First[#] - Last[#]] &;
a2 = BlockMap[G, data, 2]; // RepeatedTiming // First
b2 = Developer`PartitionMap[G, data, 2]; // RepeatedTiming // First
a === a2 === b === b2

0.24

0.23

True

But if F is Listable or composed of functions with the attribute Listable (like in our case), the following allows us to exploit that:

a3 = F[data[[1 ;; ;; 2]], data[[2 ;; ;; 2]]]; // RepeatedTiming // First
a4 = F @@ Transpose[Partition[data, 2]]; // RepeatedTiming // First
a === a3 === a4

0.0029

0.0065

True

In this case, data is a packed array and the components of F are very well vectorized functions. So this will not as efficient in other, less specific cases. Moreover, a4 might become more performant than a3 when the length of the sublists increases.

$\endgroup$

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