The Monty Hall problem, with lists#
For inspiration, see this simulation of the Monty Hall Problem using arrays.
We use arrays often in data science, but sometimes, it is more efficient to use Python lists.
To follow along in this section, you will also need more on lists.
Simulating one trial#
To operate on lists we use the Python standard random
module, instead of the Numpy random
module. The Numpy module always returns arrays, but in our case, we want to return lists.
import random
In particular, we are going to use the shuffle
function in the Python
standard random
module.
doors = ['car', 'goat', 'goat']
random.shuffle(doors)
doors
['goat', 'goat', 'car']
Here we chose a door at random. We use the standard random.choice
instead of
rng.choice
.
my_door_index = random.choice([0, 1, 2])
my_door_index
2
We get the result of staying with our original choice, and remove that option from the list of available doors.
stay_result = doors.pop(my_door_index)
stay_result
'car'
We are left with the two doors that Monty has to choose from.
doors
['goat', 'goat']
Behind one of these doors, Monty knows there is a goat. He opens the door. We simulate that by removing the first door with a goat behind it.
Remember, remove
removes only the first instance of “goat”, leaving the second, if there is one.
doors.remove('goat')
doors
['goat']
Now we have only one remaining door. The item behind that door is the result from switching from our original door.
switch_result = doors[0]
switch_result
'goat'
Many trials.#
That’s one trial. Now let’s do that 100000 times.
Here we are using range
instead of np.arange
. range
is the standard
Python equivalent of np.arange
; it has the same effect, in this case, when we
use it in a loop.
# Make 10000 trials.
n_tries = 100000
# Lists to store results from stay and switch strategy
stay_results = []
switch_results = []
for i in range(n_tries):
# Same code as above, for one trial
doors = ['car', 'goat', 'goat']
random.shuffle(doors)
my_door_index = random.choice([0, 1, 2])
stay_result = doors.pop(my_door_index)
doors.remove('goat')
switch_result = doors[0]
# Put results into result lists
stay_results.append(stay_result)
switch_results.append(switch_result)
We use the count
method of the list to count the number of “car” element in
each list, and divide by the length of the list, to get the proportion of
successes.
stay_results.count('car') / n_tries
0.33488
switch_results.count('car') / n_tries
0.66512
Compare this solution to the solution using arrays. Which solution is easier to read and understand?