Как сгруппировать по имени, сохранить ключи и имена с помощью itertools?

Я работаю с набором данных, который представляет собой простой SQL-запрос, который извлекает нужные строки.

      [(2, 5, 'JOHN K', 'YAHOO'), (2, 6, 'AARON M', 'YAHOO'), (2, 7, 'NICK C', 'YAHOO'), (1, 2, 'CELESTE G', 'GOOGLE'), (1, 3, 'RICH M', 'GOOGLE'), (1, 4, 'SANDEEP C', 'GOOGLE')]

Что у меня есть до сих пор, что дает группировку без ключей -

      import itertools
import operator


def accumulate(rows):
    # itemgetter fetches and groups them by company name(3)
    it = itertools.groupby(rows, operator.itemgetter(3))
    k = {}
    for key, subiter in it:
        k[key] = ';'.join(item[2] for item in subiter)
    return k


if __name__ == '__main__':

    rows = [(2, 5, 'JOHN K', 'YAHOO'), (2, 6, 'AARON M', 'YAHOO'), (2, 7, 'NICK C', 'YAHOO'), (1, 2, 'CELESTE G', 'GOOGLE'), (1, 3, 'RICH M', 'GOOGLE'), (1, 4, 'SANDEEP C', 'GOOGLE')] 
    groupedby = (accumulate(rows))

    print(groupedby)

Выход -

      {'YAHOO': 'JOHN K;AARON M;NICK C', 'GOOGLE': 'CELESTE G;RICH M;SANDEEP C'}

Желаемый результат сохраняет ключи и по-прежнему выполняет группировку -

      {('YAHOO,2'): '(JOHN K,5);(AARON M,6);(NICK C,7)', ('GOOGLE,1'): '(CELESTE G,2);(RICH M,3);(SANDEEP C,4)'}

Я открыт для какой-либо другой структуры данных, которая не разделена запятой, с использованием каналов или может быть кортежем.

      for key, subiter in it:
    k[key, ] = ';'.join(item[2] for item in subiter)

Любая помощь приветствуется!

1 ответ

Вот решение, использующее groupby с полным ключом, который вы хотите использовать в качестве кортежа, и помещая совпадения в список кортежей вместо строки, разделенной точкой с запятой.

      import itertools
import operator


def accumulate(rows):
    # use lambda function to build a groupby tuple from pieces (3,0)
    it = itertools.groupby(rows, lambda x: (x[3], x[0]))
    k = {}
    for key, subiter in it:
        # for the specified key, use list comprehension to create tuples of desired elements from each row in the group.
        k[key] = [(item[2], item[1]) for item in subiter]
    return k


if __name__ == "__main__":

    rows = [
        (2, 5, "JOHN K", "YAHOO"),
        (2, 6, "AARON M", "YAHOO"),
        (2, 7, "NICK C", "YAHOO"),
        (1, 2, "CELESTE G", "GOOGLE"),
        (1, 3, "RICH M", "GOOGLE"),
        (1, 4, "SANDEEP C", "GOOGLE"),
    ]
    groupedby = accumulate(rows)

    print(groupedby)

выход:

      {
 ('YAHOO', 2): [('JOHN K', 5), ('AARON M', 6), ('NICK C', 7)],
 ('GOOGLE', 1): [('CELESTE G', 2), ('RICH M', 3), ('SANDEEP C', 4)]
}
Другие вопросы по тегам