I have to create a list by varying one parameter of a function. For now, I resort on that solution:

Map[Function[m, f[arg1, arg2, m, arg4]], Range[-3,3]]
{ f[arg1,arg2,-3,arg4],
  f[arg1,arg2,3,arg4] }

It works as expected. But it requires creating a dummy pure function just for the sake of mapping a parameter to a Range. So, I wonder if there wouldn't exist a simpler and/or more elegant solution?

Obviously, there is the For loop, but I searched through the documentation and didn't find a "functional style" equivalent of that construct.

  • $\begingroup$ Thread[f[arg1,arg2,Range[-3,3],arg4] $\endgroup$
    – ciao
    Dec 9 '19 at 0:16
  • 2
    $\begingroup$ The short form for what you wrote is f[arg1, arg2, #, arg4] & /@ Range[-3, 3] $\endgroup$
    – Bob Hanlon
    Dec 9 '19 at 0:22
  • $\begingroup$ Also, SetAttributes[f, Listable]; f[arg1, arg2, Range[-3, 3], arg4] $\endgroup$
    – Bob Hanlon
    Dec 9 '19 at 0:27
  • $\begingroup$ Thanks for the comments. @ciao Wouldn't a Thread-based solution break if one of the argN is a list? $\endgroup$ Dec 9 '19 at 0:28
  • 1
    $\begingroup$ You can specify which argument is being threaded by providing a third argument to Thread: Thread[f[arg1, arg2, Range[-3, 3], arg4], List, {3}]. $\endgroup$
    – asterix314
    Dec 9 '19 at 2:36

Thread accepts 2 more arguments in addition to the target expression: a head specification (usually List) and a sequence specification to narrow down the scope of arguments to be threaded. So for example:

With[{arg1 = {1,2,3,4,5,6,7}}, Thread[f[arg1, arg2, Range[-3, 3], arg4], List, {3}]]

would only expland on the third argument and leave the rest intact.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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