# Inverting replace direction

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}


{a1 -> b1, a2 -> b2, a3 -> b3}  /.  Rule[x_, y_] -> Rule[y, x]

• You should be using :> rather than -> here, in case of assignments to x or y. Jun 20, 2020 at 15:37

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.

### 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}


Just wanted to join in on all of the fun:

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


Same output.