3
$\begingroup$

Suppose I have a list that I want to use replacement rules to replace each occurrence of a a given symbol with a randomly selected value, with this choice being randomized for each occurrence.

For a simple example, suppose list={x,x,x,x} and I want to replace each occurrence of x with a (potentially different) random integer between 1 and 5`. Defining

    rule=x->RandomInteger[5]

and evaluating list/.rule instead replaces all the instances of x with the same randomly chosen value. For example, returning {5,5,5,5} instead of {2,3,3,5}.

How can I obtain the properly randomized replacements?

$\endgroup$

2 Answers 2

6
$\begingroup$

The issue with defining rule = x -> RandomInteger[5] and evaluating it is that Mathematica evaluates this RandomInteger at the time of definition, simply storing rule = x -> 5 or similar. This in turn causes list /. rule to replace all of the x with the same value.

Instead, we need to delay this random choice so that it occurs after it has replaced each x.

A solution is to use :> (RuleDelayed) instead of -> (Rule), which holds the RHS unevaluated until the rule is used. This syntactic distinction is similar to that of = (Set) vs := (SetDelayed):

   delayRule = x :> RandomInteger[5];
   list /. delayRule
   (* {2, 3, 1, 4} *)

An alternative solution is to use Hold and ReleaseHold to obtain the desired behavior:

randomRule = x -> Hold[RandomInteger[5]];

list /. randomRule
(* {Hold[RandomInteger[5]], ...., Hold[RandomInteger[5]]}*))

% // ReleaseHold
(* {4, 2, 3, 2} *)

Observe how using Hold in our rule replaces each x with a separate copy of Hold[RandomInteger[5]]. We then ReleaseHold to have the kernel evaluate each copy, giving our separately evaluated random choices.

$\endgroup$
5
$\begingroup$

You want RuleDelayed instead of Rule so the right hand side of the rule is recalculated every time the replacement rule is applied:

rule = x:> RandomInteger[5];
{x, 10, 10, x, 10} /. rule

(* Out: {3, 10, 10, 5, 10} *)
$\endgroup$

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