Project Euler #645 -- speed up Monte-Carlo simulation in Python
Welcome to Code Review. Nice implementation, easy to read and understand.
Optimization
There are some &quot;expensive&quot; operations that can be simplified. Below I commented the relevant parts:
def Exp(D):
    # the method &quot;all&quot; takes O(D)
    while all((d == 1 for d in day_list)) == False:
        # O(D)
        zero_ind = (i for i,v in enumerate(day_list) if v == 0) 
        # O(D)
        for ind in zero_ind:
            # Here there are only O(1) operations
    return num_emperor

By \$O(D)\$ I mean that in the worst case such operation will iterate D times, where D is the number of days.
The condition in the while loop can be simplified by checking if the number of holidays is &lt; days:
def Exp(D):
    holidays = 0
    while holidays &lt; D:
        # increment holidays 
    return num_emperor

The second optimization is to avoid the inner loops. Once the new birthday has been calculated, it's enough to &quot;look around&quot; that specific day:
def Exp(D):
    # ..
    while holidays &lt; D:
        bday = np.random.randint(0,D)
        # Increment holidays only if birthday is not in a holiday
        if day_list[bday] == 0:
            holidays += 1
        day_list[bday] = 1
        num_emperor+=1

        yesterday = (bday - 1) % D
        day_before_yesterday = (bday - 2) % D
        if day_list[day_before_yesterday] == 1 and day_list[yesterday] == 0:
            day_list[yesterday] = 1
            holidays += 1

        tomorrow = (bday + 1) % D
        day_after_tomorrow = (bday + 2) % D
        if day_list[day_after_tomorrow] == 1 and day_list[tomorrow] == 0:
            day_list[tomorrow] = 1
            holidays += 1
    return num_emperor

The % operator prevents to overflow the array, so you don't need to catch exceptions.
Running the average:
avg_n_emperor = my_mean(monte_carlo(iters=1000,D=365))
# Output: 1173.786
# Running time: around 2 seconds

Regarding the style, @Peilonrayz already provided an excellent review.