Dan
Dan

Reputation: 359

Python evenly distribute value to a list in a dictionary

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!

Upvotes: 1

Views: 3991

Answers (2)

MisterMiyagi
MisterMiyagi

Reputation: 51979

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.


import random
# initial setup
employees = ['empA', 'empB', 'empC', 'empD', 'empE', 'empF']
numbers = list(range(1, 26+1))
# dict to hold assignment and randomly shuffled numbers
employee_numbers = {}
random.shuffle(numbers)
# assign shuffled numbers to employees
for idx, employee in enumerate(employees):
    employee_numbers[employee] = numbers[idx::len(employees)]
# print result
print(employee_numbers)

Upvotes: 1

AKX
AKX

Reputation: 169204

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.

Upvotes: 0

Related Questions