Splitting a list fairly
Dividing people into teams is a shuffle followed by a deal. The shuffle must be unbiased, which means using the Fisher-Yates algorithm — walking the list from the end and swapping each element with a randomly chosen earlier one — rather than the common shortcut of sorting with a random comparator.
That shortcut is genuinely broken. Sorting with a comparator returning random results produces a distribution that is measurably non-uniform, because sort algorithms make assumptions about consistency that a random comparator violates, and the outcome depends on the sorting implementation. It looks shuffled and is not.
Uneven group sizes are the other detail. When the number of people does not divide evenly, the remainder has to go somewhere, and distributing it one per team from the top of a shuffled list is fairer than always adding the extras to the last team — which otherwise systematically ends up largest.
Random is not always what you want
Purely random assignment produces unbalanced teams more often than people expect. In a group with a wide range of skill, chance regularly places the strongest few together, and for anything competitive that undermines the exercise.
Where balance matters, the usual approach is to rank participants and use snake drafting: assign in order to each team, then reverse the order for the next round, so the team picking last in one round picks first in the next. It distributes strength evenly while retaining some randomness within tiers.
Constraints are the other common requirement — keeping certain people apart, keeping others together, or balancing an attribute across teams. These make the problem substantially harder than a shuffle, since satisfying several constraints simultaneously may have no solution. Generating several arrangements and choosing one that satisfies the constraints is usually more practical than trying to construct one directly.
Using it well with a group
Randomness is often chosen for its social function rather than its statistical properties: it removes the awkwardness of picking teams by hand, and it is visibly impartial in a way a person's judgement is not. That benefit only holds if the process is transparent, so generating teams in front of everyone matters more than the algorithm.
Announce the method before generating. Whether teams are purely random or balanced by ability, and whether the result will be regenerated if it looks lopsided, are decisions that cause arguments when made after seeing the outcome. Deciding in advance that you will accept the first result — or that you will regenerate up to twice — removes the dispute entirely.
For repeated sessions with the same group, purely random assignment leads to the same people together surprisingly often. Tracking previous groupings and avoiding repeats produces a better experience, and is the same reasoning behind using a shuffled queue rather than independent draws in the random number generator.