Некоторый кодовый гольф (вроде - очевидно, что возможно больше запутывания) после ответа eumiro, отметив, что itertools.groupby можно использовать дважды (один раз, чтобы получить наборы букв в порядке появления, что-то, о чем я не думал - и снова, чтобы фактически создать пары ключ-значение для словаря).
from itertools import groupby
data = ['good', 'god', 'hell', 'hello']
dict((''.join(k), list(v)) for k, v in groupby(data, lambda x: zip(*groupby(x))[0]))
Как это работает: каждое слово сначала обрабатывается с помощью lambda x: zip(*groupby(x))[0]
. То есть мы берем список пар (буква, группировщик-объект), созданных генератором groupby
, преобразуем его в пару (списки букв, список-группировщиков-объектов) (содержимое генератора неявно оценивается для передачи в zip
) и отбрасывает объекты list-grouper, которые нам не нужны. Затем мы группируем весь список слов в соответствии со списком букв, созданным каждым словом, преобразуем список букв обратно в строку, оцениваем генераторы объекта группирования, чтобы получить соответствующие слова, и используем эти значения ключа пары для построения финала dict
.
Редактировать: Я думаю, что сделать лямбду в ''.join
шаге чище:
from itertools import groupby
data = ['good', 'god', 'hell', 'hello']
dict((k, list(v)) for k, v in groupby(data, lambda x: ''.join(zip(*groupby(x))[0])))