While yes, pair programming is preferred over just pushing to master, I think code reviews (and moreover formal code reviews) are better than pair programming for the final OK.
My anecdotal experience with my own teams is relying too much on pairing as a training mechanism, especially between senior and junior, has a couple of issues. The first is tradeoff between training quality and utilisation - it may shorten the training cycle but the payoff isn't high enough for the output constraint on the more senior member. The second is I've sometimes had trouble weaning the junior off always having guidance on tap and it takes them longer to develop confidence to break through certain problems alone.
If you're reviewing someone's code at the code review stage, you can only do so much. If it's working, tested code then asking for major changes is either pointless or very costly; there's little point in suggesting out a better way of approaching a problem if it requires major surgery. Unless you spot a potential bug or something that will cause major problems, you're realistically restricted to suggesting minor changes like style suggestions or better names for things.
With pair programming you have two people collaborating on a design from the start where suggestions for better ways of doing things are much easier to incorporate. If pair programming for a complete feature is either not feasible or undesirable for some reason it is at least often worth pairing to start a feature off.
Code review on the other hand also has some benefit in getting a fresh pair eyes on a piece of code to spot obvious mistakes that people elbows in deep in it have glossed over or find hard to see, such as left-in debugging code or user credentials.