import itertools
import random
import bisect


def weighted_choice(distribution):
    """Choose an element from a weighted distribution.

    Algorithm is taken from the documentation for the Python random module.

    distribution
        A sequence of (element, weight) tuples."""
    choices, weights = zip(*distribution)
    cdist = list(itertools.accumulate(weights))
    x = random.uniform(0,cdist[-1])
    return choices[bisect.bisect(cdist,x)]