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.

I would like to create a mapping from a list and I am wondering if there is a slick way of doing it.

For example, consider the list

ls = WaveletFilterCoefficients[DaubechiesWavelet[2], "PrimalHighpass"]

{{-2, -0.0915064},{-1, -0.158494},{0, 0.591506},{1, -0.341506}}

I would like to define a function that maps

 -2 -> -0.0915064
 -1 -> -0.158494
  0 ->  0.591506
  1 -> -0.341506

and all other integers to zero.

Any suggestions?

share|improve this question

5 Answers 5

up vote 11 down vote accepted

Scan[] is your friend:

Scan[(f[First[#]] = Last[#]) &, 
  WaveletFilterCoefficients[DaubechiesWavelet[2], "PrimalHighpass"]];
f[_] = 0;

??f
  Global`f
f[-2]=-0.0915064

f[-1]=-0.158494

f[0]=0.591506

f[1]=-0.341506

f[_]=0
share|improve this answer

Another way is to use Map i.e. /@ :

 l= WaveletFilterCoefficients[DaubechiesWavelet[2], "PrimalHighpass"];    
 Set[f[#[[1]]], #[[2]]] & /@ l;  
 f[_] = 0;
 f /@ Range[-3, 3]
 (*
 ==>  {0, -0.0915064, -0.158494, 0.591506, -0.341506, 0, 0}
 *) 
share|improve this answer
1  
The problem with this is that Map[] can have the side-effect of producing output, which might be problematic if the list is long, and you've forgotten the semicolon. Scan[] is guaranteed not to produce output. –  J. M. Feb 16 '12 at 0:51
1  
@J.M. Sorry, where have I missed the semicolon ? –  Artes Feb 16 '12 at 0:57
    
You didn't, but it's a common mistake to forget semicolons for delineating different expressions. –  J. M. Feb 16 '12 at 1:06
1  
@J.M. I'd add that even if you don't miss a semicolon, memory is allocated and list is internally created when Map is used. So, Map and Scan have very different memory use characteristics. If Scan can be used (meaning no output is needed), it is IMO better to use it than Map. Also, conceptually, this makes an intent of producing side-effects more clear / transparent. –  Leonid Shifrin Feb 16 '12 at 7:52
1  
@J.M. But I must admit that I also sometimes use Map in such situations (just because its syntax is more concise :)) –  Leonid Shifrin Feb 16 '12 at 13:19

Why not use Replace?

ls = WaveletFilterCoefficients[DaubechiesWavelet[2], "PrimalHighpass"];    

Attributes[func] = {Listable};
func[x_] := Replace[x, Apply[Rule, ls, {1}]];

func[{1, 0, -1, -2}]

(*
   ==> {-0.341506, 0.591506, -0.158494, -0.0915064}
*)
share|improve this answer

You could easily create a pattern doing the replacement for you:

ls = WaveletFilterCoefficients[DaubechiesWavelet[2], "PrimalHighpass"];
rule = Rule @@@ ls
{-2 -> -0.0915064,
 -1 -> -0.158494,
  0 ->  0.591506,
  1 -> -0.341506}

This can now be used as usual, for example

{-1, 1} /. rule
{-0.158494, -0.341506}

If you want to map all integers to 0, append (!) this to your rule list:

AppendTo[rule, _ -> 0];
{-2 -> -0.0915064,
 -1 -> -0.158494,
  0 ->  0.591506,
  1 -> -0.341506,
  _ -> 0}

Be careful though, because when you apply this to a list as before it'll match the whole list as _, replacing it with 0:

1 /. rule
-0.341506
{0, 1} /. rule
0

To properly do the list replacement in this case, use something like

myReplace = # /. rule &;
myReplace /@ {0, 1}
{0.591506, -0.341506}
share|improve this answer
4  
If your list is long you will want rule = Dispatch[ Rule @@@ ls ] for performance. –  Mr.Wizard Feb 16 '12 at 5:45

Depending on your application this may be most efficient:

pts =
  {{-2, -0.0915064},
   {-1, -0.158494},
   { 0,  0.591506},
   { 1, -0.341506}};

f = Interpolation[pts, InterpolationOrder -> 0];

f /@ {1, -1, -2, 0}
{-0.341506, -0.158494, -0.158494, 0.591506}

This assumes that your function will only be given arguments that are in your list rather that points between them, which will otherwise effectively give f[Floor[#]] &.


Also, I recognize the advantage of Scan but I cannot pass the syntactical elegance of:

(f[#] = #2) & @@@ pts; 
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.