Random from Dictionary

Tim Peters tim.one at home.com
Sat Oct 20 16:21:38 EDT 2001


[Tim Payne]
> ...
> I'm trying to obtain x number of random unique items from a
> dictionary. This would have been easy to do with a list, but I need
> the dictionary for other parts of the script.

In 2.1 or before, there's no simpler way than to materialize a list and use
that, like:

def random_from_dict(d, x):
    "Return and remove (no more than) x random (k, v) pairs from d."
    import random
    items = d.items()
    random.shuffle(items)
    result = items[:x]
    for k, v in result:
        del d[k]
    return result

Season to taste.  In 2.2 you could use a more memory-efficient scheme via
iterating over d directly:

def random_from_dict(d, x):
    "Return and remove x random (k, v) pairs from d."
    from random import random
    n = float(len(d))  # float() so x/n later doesn't truncate to 0
    if not 1 <= x <= n:
        raise ValueError("go away")
    result = []
    for k in d:
        # Choose this item with probability x/n.
        if random() <= x/n:
            result.append((k, d[k]))
            x -= 1
            if x == 0:
                break
        n -= 1
    for k, v in result:
        del d[k]
    return result

> I've tried popitem(), but arbitrary values just aren't good enough.

If I were you, I'd think about changing the algorithm so that arbitrary
values are good enough <0.9 wink>.

popitem()-is-fast-and-threadsafe-but-not-pretty-ly y'rs  - tim





More information about the Python-list mailing list