# Elegant way for element-wise application of a list of functions

For given functions $f,g,\cdots$ I want to define a pure function that, when applied to any list $\{x,y,\cdots\}$ (of the same length as $\{f,g,\cdots\}$), produces $\{f[x],g[y],\cdots\}$. Two ways to achieve this are

{f@#[[1]],g@#[[2]],...} &


and

MapThread[
#1[#2] & (* or Apply[#1,{#2}] & *),
{{f,g,...},#}
] &


With all of Mathematica's built in functions, however, I would be surprised if there does not exist a slicker way to do this. Thus my question is: is there a more elegant way to do the above?

For concreteness let's take just to functions $\{f,g\}$ and apply it to $\{x,y\}$, yet I'm hoping for an answer that generalizes to more than two functions.

Although I would expect that this has been asked here before I cannot find it.

• My first approach would have been the MapThread you show here. – Szabolcs Nov 2 '16 at 12:57
• Yeah, I feel like this is one of the things that MapThread was designed for. – march Nov 2 '16 at 15:42
• For the first argument of MapThread, you could use Compose rather than a pure function: MapThread[Compose, {{f, g, ...}, #}] &. – user31159 Nov 2 '16 at 19:15
• @xavier: Thanks, that's nice indeed! If you turn your suggestion into an answer I'll accept it – Jules Lamers Nov 3 '16 at 10:27
• @JulesLamers Please feel free to make it an answer if it satisfies you. (It is also OK to accept one's own answer.) – user31159 Nov 3 '16 at 18:13

lst1={f,g,h};


for example they may be Cos, Sin, Exp and so on, and lst2 is the list of numbers to which you want to apply the heads:

lst2={a,b,c};


A most simple way seems me to be this:

    Transpose[{lst1, lst2}] /. {x_, y_} -> x[y]

(*   {f[a], g[b], h[c]}  *)


Another way would be to first introduce a function:

   s[x_, y_] := x[y]


and with its use do this:

MapThread[s, {lst1, lst2}]

(*  {f[a], g[b], h[c]}  *)


or this:

Inner[s, lst1, lst2, List]

{f[a], g[b], h[c]}


One can probably find something else, but in the moment I do not see.

Have fun!

I think the MapThread approach is already elegant. Anyway, the following is the shortest solution so far:

#@#2 & @@@ ArcTan[{f, g}, #] &

• Do you have a specific reason for using ArcTan? – Jules Lamers Nov 2 '16 at 12:54
• @JulesLamers No, if you use List, then you only got {f[g], x[y]}. I use ArcTan because it owns Listable attribute and seems not to evaluate to other things even if its 2nd argument is some special number e.g. ArcTan[f, 0] still outputs ArcTan[f, 0]. – xzczd Nov 2 '16 at 12:56
• (You're right, my suggestion to use List instead of ArcTan was incorrect; I edited my comment accordingly) – Jules Lamers Nov 2 '16 at 13:00

One can use the Listable attribute to apply a list of function to lists of arguments. One can extend it easily to multiple lists of arguments (see last example).

Either via Function:

Function[{x, y}, x[y], Listable][{f, g, h}, {x, y, z}]
(*  {f[x], g[y], h[z]}  *)


Or via a symbol:

Block[{threadApply},
threadApply[{f, g, h}, {x, y, z}]
]
(*  {f[x], g[y], h[z]}  *)


With the symbolic form, it's easy to deal with an arbitrary number of arguments:

Block[{threadApply},
threadApply[{f, g, h}, {a, b, c}, {x, y, z}]
]
(*  {f[a, x], g[b, y], h[c, z]}  *)

]
(*  {f[], g[], h[]}  *)


This is also possible with a slight modification of the OP's original MapThread:

MapThread[#1[##2] &, {{f, g, h}, {a, b, c}, {x, y, z}}]
(*  {f[a, x], g[b, y], h[c, z]}  *)

• Cool, thanks for your answer! It's nice to see the versions with several arguments as well. Just a small question about the final version: why do you prefer #1[##2]& over Compose? – Jules Lamers Dec 12 '16 at 12:28
• @JulesLamers You're welcome! Note that Compose[f, a, x] and #1[##2]&[f, a, x] are not the same. There's also this warning: reference.wolfram.com/language/ref/Compose.html – Michael E2 Dec 12 '16 at 13:15
• As for the first of course you're quite right, I was thinking about the two-argument case. Regarding the latter I did see that warning, but since Compose and Composition are different I'm not sure what to do with it; am I supposed not to use Compose any more? – Jules Lamers Dec 12 '16 at 13:25
• @JulesLamers I suppose Compose is not going away (since it hasn't after nine version updates). I'll probably use #1[#2]& or Composition with # and & depending on the case. It's not a big deal to me, but I'd rather not have my code dependent on it. Even if it were to go away, it's easy enough to add a definition. – Michael E2 Dec 12 '16 at 13:37

Encouraged by the comments I think that the following slight improvement, suggested by xavier (user31159), of the second attempt I included in my question is (at least quite close to) what I was hoping for:

MapThread[
Compose,
{{f,g,...},#}
] &


Thanks for the other suggestions as well!

• Altho Compose[] is obsolete; it's quite nice. Anyway: Inner[Compose, lst1, lst2, List]`, if you want something slot-free. – J. M. will be back soon Dec 12 '16 at 10:49