8
$\begingroup$

I just have a simple problem. I have a list such that,

rep = { a1 -> b1, a2 -> b2, a3 -> b3};

I want to invert replace direction such that,

{ b1 -> a1, b2 -> a2, b3 -> a3}
$\endgroup$

4 Answers 4

8
$\begingroup$
{a1 -> b1, a2 -> b2, a3 -> b3}  /.  Rule[x_, y_] -> Rule[y, x]
$\endgroup$
1
  • 4
    $\begingroup$ You should be using :> rather than -> here, in case of assignments to x or y. $\endgroup$
    – Mr.Wizard
    Jun 20, 2020 at 15:37
14
$\begingroup$

When we have a long list of rules it would be resonable choosing a functional approach, which is much faster than rule based one. In such cases consider e.g.

Reverse /@ rep

Sometimes it would be more efficient using Transpose twice than Map once, e.g.

Rule @@@ Transpose @ Reverse @ Transpose[ List @@@ rep]

Nonetheless ususally we need not to play with long lists and a simple pattern matching is quite sufficient, and so another approach might be e.g.

rep /. Rule[a_, b_] :> Rule[b, a]
 {b1 -> a1, b2 -> a2, b3 -> a3}

Mind using RuleDelayed in cases when it matters instead of Rule.

$\endgroup$
12
$\begingroup$

Part

Part is a general approach to this kind of reordering challenge:

rep = {a1 -> b1, a2 -> b2, a3 -> b3};

rep[[All, {2, 1}]]
{b1 -> a1, b2 -> a2, b3 -> a3}

Reference:

Reverse

Also there is a faster form of Reverse:

Reverse[rep, 2]
{b1 -> a1, b2 -> a2, b3 -> a3}

Slot / Function

Slot notation is compact though performance tends to be less than the options above:

#2 -> # & @@@ rep
{b1 -> a1, b2 -> a2, b3 -> a3}

Noteworthy is that unlike Part and Reverse this replaces heads. For example if you have a mixed list of Rule and RuleDelayed:

rep = {a1 -> b1, a2 :> b2, a3 -> b3};

#2 -> # & @@@ rep
rep[[All, {2, 1}]]
{b1 -> a1, b2 -> a2, b3 -> a3}

{b1 -> a1, b2 :> a2, b3 -> a3}

Performance

Comparative timings with a large list of rules:

rep =
  Rule @@@ RandomInteger[1*^7, {1*^6, 2}];

rep /. (x_ -> y_) :> (y -> x); // RepeatedTiming
#2 -> # & @@@ rep;             // RepeatedTiming
Reverse /@ rep;                // RepeatedTiming
rep[[All, {2, 1}]];            // RepeatedTiming
Reverse[rep, 2];               // RepeatedTiming
{0.62, Null}

{0.60, Null}

{0.475, Null}

{0.346, Null}

{0.334, Null}
$\endgroup$
1
$\begingroup$

Just wanted to join in on all of the fun:

Rule[Last@#,First@#]&/@rep

Same output.

$\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.