# Python evenly distribute value to a list in a dictionary

4119 views
10

I have the following code which assigns numbers at random to employees:

``````emp_numbers = {}
employees = ['empA', 'empB', 'empC', 'empD', 'empE', 'empF']
numbers = 26
for x in employees:
emp_numbers[x] = []
emp = list(emp_numbers.keys())

for number in range(1, numbers+1):
emp_name = choice(emp);
emp_numbers[emp_name].append(number)
print (emp_numbers)
``````

Output:

``````{'empA': [4, 25], 'empB': [2, 10, 11, 15, 18, 20, 22, 23], 'empC': [5, 13, 21, 24], 'empD': [3, 6, 7, 8, 12, 16, 19, 26], 'empE': [14], 'EmpF': [1, 9, 17]}
``````

It works great. However, I don't know how to get it to distribute the numbers as evenly as possible. Some employees are getting 2 numbers, some have 8. Any advice on how to get it do that?

Thanks!

10

Assuming the count of numbers is evenly divisible with the number of employees, you could go about it this way:

``````import random
import collections

employees = ["empA", "empB", "empC", "empD", "empE", "empF"]  # employee names
numbers = list(range(1, 27))  # numbers from 1..26

emp_numbers = collections.defaultdict(list)  # collects the employee numbers
random.shuffle(numbers)  # shuffle the numbers to distribute

for i, number in enumerate(numbers):  # get the index of the number and the number
employee = employees[i % len(employees)]  # round-robin over the employees...
emp_numbers[employee].append(number)  # ... and associate a number with a name.

print(emp_numbers)
``````

outputs e.g.

``````{'empF': [25, 4, 9, 21], 'empD': [2, 10, 3, 11], 'empE': [18, 5, 17, 15], 'empB': [7, 24, 26, 6, 8], 'empC': [1, 14, 13, 12], 'empA': [16, 23, 20, 19, 22]}
``````

If the numbers aren't evenly divisible, some folks will get more numbers than others.

posted this
9

Since you want to assign all numbers, you can randomise the order of numbers instead of employees:

``````numbers = list(range(1, 27))
random.shuffle(numbers)
``````

You can then use slicing to get an even count of numbers for every employee:

``````for idx, employee in enumerate(employees):
emp_numbers[employee] = numbers[idx::len(employees)]
``````

The `[start::n]` syntax selects every `n`'th item beginning at `start`. The first employee gets item 0, 6, 12, ..., the second gets item 1, 7, 13, ..., and so on.

posted this