0
$\begingroup$

Why does the following code give me a warning, but then still work?

a1={{1,2},{3,1}}
a2={"foo","bar"}
a1/.{x_Integer,y_Integer}->{x,a2[[y]]}

After a "Part: The expression y cannot be used as a part specification" warning, it correctly gives this:

{{1,bar},{3,foo}}

$\endgroup$
  • 3
    $\begingroup$ Use RuleDelayed. a1/.{x_Integer,y_Integer} :> {x,a2[[y]]}. $\endgroup$ – Shredderroy Jun 7 '19 at 18:04
2
$\begingroup$

Consider the rule:

a2={"foo", "bar"};
{x_Integer, y_Integer} -> {x, a2[[y]]}

Part::pkspec1: The expression y cannot be used as a part specification.

{x_Integer, y_Integer} -> {x, {"foo", "bar"}[[y]]}

Notice how a2[[y]] tried to evaluate, but issues a message because you can't use y as a part specification. Since Mathematica typically returns inputs back as outputs when things go wrong, when you later substitute values for x and y with your rule application you get:

{{1, {"foo", "bar"}[[2]]}, {3, {"foo", "bar"}[[1]]}}

which can now evaluate because the part specification is an integer.

As Shredderroy says, the proper way to do this is to use RuleDelayed (:>) instead of Rule (->).

| improve this answer | |
$\endgroup$

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.