def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, dp_must_exit=None):
    'This works inplace'
    random.shuffle(entrances)
    random.shuffle(caves)
    used_caves = []
    while must_be_exits:
        exit = must_be_exits.pop()
        cave = None
        for candidate in caves:
            if (not isinstance(candidate, str)):
                cave = candidate
                break
        if (cave is None):
            raise RuntimeError('No more caves left. Should not happen!')
        connect_two_way(world, exit, cave[(- 1)], player)
        if (len(cave) == 2):
            entrance = entrances.pop()
            if ((world.mode[player] != 'inverted') and (entrance == 'Dark Death Mountain Ledge (West)')):
                new_entrance = entrances.pop()
                entrances.append(entrance)
                entrance = new_entrance
            if ((world.mode[player] == 'inverted') and (entrance == dp_must_exit)):
                new_entrance = entrances.pop()
                entrances.append(entrance)
                entrance = new_entrance
            connect_two_way(world, entrance, cave[0], player)
        elif (cave[(- 1)] == 'Spectacle Rock Cave Exit'):
            for exit in cave[:(- 1)]:
                connect_two_way(world, entrances.pop(), exit, player)
        else:
            caves.append(cave[0:(- 1)])
            random.shuffle(caves)
            used_caves.append(cave[0:(- 1)])
        caves.remove(cave)
    for cave in used_caves:
        if (cave in caves):
            for exit in cave:
                connect_two_way(world, entrances.pop(), exit, player)
            caves.remove(cave)
This works inplace
def connect_mandatory_exits(world, entrances, caves, must_be_exits, player, dp_must_exit=None):
    
    random.shuffle(entrances)
    random.shuffle(caves)
    used_caves = []
    while must_be_exits:
        exit = must_be_exits.pop()
        cave = None
        for candidate in caves:
            if (not isinstance(candidate, str)):
                cave = candidate
                break
        if (cave is None):
            raise RuntimeError('No more caves left. Should not happen!')
        connect_two_way(world, exit, cave[(- 1)], player)
        if (len(cave) == 2):
            entrance = entrances.pop()
            if ((world.mode[player] != 'inverted') and (entrance == 'Dark Death Mountain Ledge (West)')):
                new_entrance = entrances.pop()
                entrances.append(entrance)
                entrance = new_entrance
            if ((world.mode[player] == 'inverted') and (entrance == dp_must_exit)):
                new_entrance = entrances.pop()
                entrances.append(entrance)
                entrance = new_entrance
            connect_two_way(world, entrance, cave[0], player)
        elif (cave[(- 1)] == 'Spectacle Rock Cave Exit'):
            for exit in cave[:(- 1)]:
                connect_two_way(world, entrances.pop(), exit, player)
        else:
            caves.append(cave[0:(- 1)])
            random.shuffle(caves)
            used_caves.append(cave[0:(- 1)])
        caves.remove(cave)
    for cave in used_caves:
        if (cave in caves):
            for exit in cave:
                connect_two_way(world, entrances.pop(), exit, player)
            caves.remove(cave)