pythonpython-itertools

How to assign each item in a list an equal amount of items from another list in python


Let's say I have a list of people

['foo','bar','baz']

and a list of items

['hat','bag','ball','bat','shoe','stick','pie','phone']

and I want to randomly assign each person an equal amount of items, like so

{
'foo':['hat','bat','stick'],
'bar':['bag','shoe','phone'],
'baz':['ball','pie']
}

I think itertools is the job for this, but I couldn't seem to find the right function as most itertools functions seem to just work on one object.

EDIT: Order does not matter. I just want to randomly assign each person an equal amount of items.


Solution

  • Another solution, using itertools.cycle:

    import random
    from itertools import cycle
    
    persons = ["foo", "bar", "baz"]
    items = ["hat", "bag", "ball", "bat", "shoe", "stick", "pie", "phone"]
    
    random.shuffle(items)
    
    out = {}
    for p, i in zip(cycle(persons), items):
        out.setdefault(p, []).append(i)
    
    print(out)
    

    Prints (for example):

    {
        "foo": ["phone", "pie", "bat"],
        "bar": ["bag", "stick", "hat"],
        "baz": ["shoe", "ball"],
    }
    

    If there could be fewer items than persons and each person should have key in output dictionary you can use:

    import random
    from itertools import cycle
    
    persons = ["foo", "bar", "baz"]
    items = ["hat", "bag", "ball", "bat", "shoe", "stick", "pie", "phone"]
    
    random.shuffle(items)
    random.shuffle(persons)  # to randomize who gets fewest items
    
    out = {p: [] for p in persons}
    for lst, i in zip(cycle(out.values()), items):
        lst.append(i)
    
    print(out)