3
$\begingroup$

I have this code:

elList = {"H", "C", "N", "O", "F", "Cl"}; els = {"Ca", "O", "C", "Si", "H"}; corr = ConstantArray[1.0, Length@els]; For[i = 1, i <= Length@els, i++, If[!MemberQ[elList, els[[i]]], corr[[i]] = 1.13]; ] 

What would be the best way to replace the loop, in other words, how to replace it in the Mathematica way?

My only idea was:

(MemberQ[elList, #] & /@ els) /. {True -> 1.0, False -> 1.13} 

Is there a better way or other way?

$\endgroup$

3 Answers 3

11
$\begingroup$

You can rewrite your idea using If as follows:

If[MemberQ[elList, #], 1., 1.13] & /@ els 
{1.13, 1., 1., 1.13, 1.} 

However you may find on larger problems that repetitive use of MemberQ is not as fast as you would like, so consider a hash table in the form of an Association, or if using an older version of Mathematica a Dispatch table.

Create a list of Rule expressions using Thread:

rules = Thread[elList -> 1.0] 
{"H" -> 1., "C" -> 1., "N" -> 1., "O" -> 1., "F" -> 1., "Cl" -> 1.} 

Convert into optimized forms with Association or Dispatch

asc = Association[rules]; disp = Append[rules, _ -> 1.13] // Dispatch; 

Apply the hash tables:

Lookup[asc, els, 1.13] Replace[els, disp, {1}] 
{1.13, 1., 1., 1.13, 1.} {1.13, 1., 1., 1.13, 1.} 
  • Note: in Lookup the third parameter specifies the default value; in Replace the third parameter is the levelspec on which to operate.

Recommended reading:

$\endgroup$
1
$\begingroup$

If speed is not you concern, may be this can be worth a try

common = Intersection[elList, els]; u = Map[ Position[els, # ] &, common ] ; corr[[ Flatten[u] ]] = 1.13 

This can be fit in a single line, and is almost readable

corr[[ Flatten[ Position[els, # ] & /@ Intersection[elList, els] ] ]] = 1.13 

and will seem even more nice if you use (elList esc inter esc els) in place of Intersection[elList,els] - the parentheses around the intersection are required, the precedence of Intersection in operator form seems to be low.

$\endgroup$
0
$\begingroup$

Here's a little one-liner without If, probably not fast on large lists:

corr = (! MemberQ[elList, #] & /@ els) /. {True -> 1.13, False -> 1.0} 
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.