So, I was coding a django site which required displaying random ads on a page, each ad is given a weight which determines the frequency at which the ad is displayed. I will admit that my first thought was far from optimal, but I later came across a post on stackoverflow.com, with a more appropriate algorithm. The code on stackoverflow was written in C#, which is just... ugly, so here is the python version.
def random_by_weight(items, attr='weight'): """ Randomly selects one item from 'items', using the 'attr' property as a weight field. """ total_weight = sum((getattr(i, attr) for i in items)) rweight = random.randint(0, total_weight) for item in items: if rweight <= getattr(item, attr): return item rweight -= getattr(item, attr)
...and there you have it.
RSS