Skip to content
Hello Python

Checking your account…

Sign in to save your code and progress across devices. The lesson and problem statement remain public.

Loading the interactive Practice workspace.If it does not appear, the problem and learning material remain readable, but browser execution is unavailable.Reload Practice workspace

Problem

Implement fisher_yates(values, choices). Return a shuffled copy. For i from n-1 down to 1, choices[n-1-i] is a valid j in [0,i]; swap indexes i and j.

Starter code

def fisher_yates(values, choices):
    pass
Test cases

deterministic-swaps

{
  "args": [
    [
      1,
      2,
      3,
      4
    ],
    [
      1,
      0,
      1
    ]
  ]
}

Expected: [3,4,1,2]

self-swaps

{
  "args": [
    [
      1,
      2,
      3
    ],
    [
      2,
      1
    ]
  ]
}

Expected: [1,2,3]

Wizard outline
  1. Step 1: Protect the caller input

    Create the output list without mutating the supplied sequence. The exercise contract returns a shuffled copy.

  2. Step 2: Place the final element

    Use one supplied choice to swap the last position. Fisher-Yates fixes one tail position per iteration.

  3. Step 3: Place every remaining tail position

    Walk backward and consume one choice per swap. After placing index i, later positions never need to move again.

Footguns and prerequisites
  • Choosing j from the full array at every step biases the permutation.
  • Mutating values violates the returned-copy contract.
  • functions
  • lists and tuples
  • control flow
Reviewed references
Recommended approach and implementation

Copy the input and perform the supplied Fisher-Yates swap for every shrinking suffix boundary.

Why it works: At boundary i, the supplied choice selects one of exactly i+1 remaining candidates for position i. The swap fixes that position and never revisits it, yielding the specified permutation without mutating input.

def fisher_yates(values, choices):
    shuffled = list(values)
    for offset, index in enumerate(range(len(shuffled) - 1, 0, -1)):
        choice = choices[offset]
        shuffled[index], shuffled[choice] = shuffled[choice], shuffled[index]
    return shuffled