Как сделать равномерное распределение фамилий по группам?
Выкатил для теста из доменного каталога список фамилий всех сотрудников (550 человек) в файл users.txt.def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]

#Считываем, убираем дубликаты, сортируем
names = sorted({line.strip() for line in open('users.txt', encoding='utf-8')})
#Разбиваем на примерно равные части и генерируем словарь,
#ключом которого служат первая буква первой и последней фамилии в списке.
catalog = {'{}-{}'.format(item[0][0], item[-1][0]):item for item in chunks(names, 100)} Обновление: Предыдущий вариант допускает пересечение групп. Поэтому я накидал другой.from itertools import groupby
from operator import itemgetter

# Разбиваем на группы по первой букве
def chunks(items):
    for letter, names in groupby(sorted(items), key=itemgetter(0)):
        yield list(names)


# Сливаем вместе группы меньше min_len в группы не больше max_len
def reshape(items, min_len, max_len):
    buffer = []
    for item in items:
        if len(buffer) >= max_len:
            yield sorted(buffer)
            buffer = []
        if len(item) <= min_len:
            buffer += item
        else:
            yield item
    yield sorted(buffer)

            
#Считываем и сортируем
names = sorted(line.strip() for line in open('users.txt', encoding='utf-8'))
#Разбиваем на примерно равные части
groups_list = reshape(chunks(names), 50, 100)
#генерируем словарь ключом которого служат первая буква первой и последней фамилии в списке
catalog = {'{}-{}'.format(item[0][0], item[-1][0]):item for item in groups_list}
Допустим есть 100 человек, их фамилии начинаются на 5 букв т.е. в среднем на букву должно быть 20 чел. Делаем цикл с проверкой если в следующей букве меньше 20 чел, значит можно объединять.