# Map vs listable [duplicate]

What's the difference between setting a function's attribute as Listable and using Map? I understand that Map is more specific, the question is rather about action on single depth lists.

The main difference can been seen when dealing with list of lists. Consider the following list:

lis = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}};


Lets create a Listable function g

SetAttributes[g, Listable]


Now we Map a non-listable function f and apply the listable function g

Map[f, lis]

(* {f[{1, 2, 3}], f[{3, 4, 5}], f[{5, 6, 7}]} *)

g[lis]

(* {{g[1], g[2], g[3]}, {g[3], g[4], g[5]}, {g[5], g[6], g[7]}} *)


Clearly the Listable function g, continues until it's applied down to a non-list expression. Whereas Map by default applies to Level 1. One can get the same behavior with Map by using the 3rd argument (level specification):

Map[f, lis, {2}]

(* {{f[1], f[2], f[3]}, {f[3], f[4], f[5]}, {f[5], f[6], f[7]}} *)


On Single-depth lists, they both behave the same:

lis2 = {1, 2, 3, 4, 5, 6};

Map[f, lis2]
g[lis2]

(*
{f[1], f[2], f[3], f[4], f[5], f[6]}
{g[1], g[2], g[3], g[4], g[5], g[6]}
*)


Performance does not seem to vary much either. Consider the following functions:

SetAttributes[k, Listable];
k[x_]:= x^2 + 2x
u[x_]:= x^2 + 2x


Let's apply them to a large list:

lis3 = RandomReal[2, 10^6];
k[lis3]; // RepeatedTiming
Map[u, lis3]; // RepeatedTiming

(* {1.26, Null}
{1.242, Null} *)


Of course, if you are going to use Map, you're better off using a pure function since that increases performance by a lot:

Map[#^2 + 2 # &, lis3]; // RepeatedTiming


{0.065, Null}

To be fair, I should also mention that you can make a Listable pure function (see comments) that performs about the same as Map with a pure function. As Szabolcs mentioned in the comments here is an example where the Listable version appears to have no Map counterpart:

g[{1, {2, 3}, 4, h[x]}]

(* {g[1], {g[2], g[3]}, g[4], g[h[x]]} *)


So at least, that's a difference. And I'm sure one can come up with many such examples.

• If you define k and u as #^2 + 2 # &, set k to be Listable, and then do k[lis3] vs u /@ lis3, my machine says that the former is even faster. Apr 26, 2016 at 19:55
• @march. On mine it's slower, but I should probably mention that option too to be fair. Apr 26, 2016 at 20:00
• g[{1, {2, 3}, 4, f[x]}] is a good example to include too. This cannot be done with Map at all, not even by mapping at level -1. Apr 26, 2016 at 20:48
• @Szabolcs it comes close, oh so close. {f[1], {f[2], f[3]}, f[4], h[f[x]]} Apr 26, 2016 at 21:08
• @Szabolcs. Thanks, I included your example. Apr 26, 2016 at 21:22