Inverting replace direction
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:
- Head and everything except Head?
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}
{a1 -> b1, a2 -> b2, a3 -> b3} /. Rule[x_, y_] -> Rule[y, x]