7

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}
Artes
  • 57,212
  • 12
  • 157
  • 245
Saesun Kim
  • 1,810
  • 13
  • 24

4 Answers4

14

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.

Artes
  • 57,212
  • 12
  • 157
  • 245
12

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}

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
8
{a1 -> b1, a2 -> b2, a3 -> b3}  /.  Rule[x_, y_] -> Rule[y, x]
PaulCommentary
  • 1,482
  • 7
  • 12
1

Just wanted to join in on all of the fun:

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

Same output.

CA Trevillian
  • 3,342
  • 2
  • 8
  • 26