Задать вопрос
@VaniLuksh

Как сгруппировать списки по двум элементам?

Имеется список, состоящий из списков - ('Категория', 'Товар', 'Цена', 'Номер склада'). Надо сгруппировать списки по категории и номеру склада, так чтобы цены на каждый товар из категории на определенном складе тоже сложились.

list_in = [['Игрушки', 'Мяч надувной', '300', '1'], ['Игрушки', 'Бионикл', '8000', '1'], ['Ткань', 'Вельвет', '1000', '2'], ['Ткань', 'Джинса', '500', '2'], ['Игрушки', 'Бионикл', '1000', '2']]


Эти списки надо сгруппировать следующим образом:

list_out = [['Игрушки', '8300', '1'], ['Ткань', '1500', '2'], ['Игрушки', '1000', '2']]
  • Вопрос задан
  • 549 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 2
0xD34F
@0xD34F
key = lambda item: (item[0], item[3])
keys = set(map(key, list_in))
list_out = [ [ k[0], sum(int(n[2]) for n in list_in if k == key(n)), k[1] ] for k in keys ]
Ответ написан
aRegius
@aRegius
Python Enthusiast
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> for i in list_in:
	        d[(i[0], i[-1])] += int(i[-2])
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
UPD: Поправил чуть способ со счетчиком:
In [1]: list_in = [['Игрушки', 'Мяч надувной', '300', '1'], ['Игрушки', 'Бионикл', '8000', '1'], ['Ткань', 'Вельвет', '1000', '2'], ['Ткань', 'Джинса', '500', '2'], ['Игрушки', 'Бионикл', '1000', '2']]

In [2]: from collections import Counter

In [3]: c = Counter(); list(map(c.update, ({(cat, stor): int(price)} for cat, name, price, stor in list_in)))
Out[3]: [None, None, None, None, None]

In [4]: c
Out[4]: Counter({('Игрушки', '1'): 8300, ('Игрушки', '2'): 1000, ('Ткань', '2'): 1500})

In [5]: [[*k, v] for k, v in c.items()]
Out[5]: [['Игрушки', '1', 8300], ['Ткань', '2', 1500], ['Игрушки', '2', 1000]]


Но иногда нужно не просто считать, а что-то еще более сложное делать после группировки, тогда больше подойдёт вот такой вариант:
In [11]: from itertools import groupby                                                              

In [12]: [[*k, sum(int(rr[2]) for rr in v)] for k, v in groupby(list_in, lambda r: (r[0], r[-1]))]
Out[12]: [['Игрушки', '1', 8300], ['Ткань', '2', 1500], ['Игрушки', '2', 1000]]

Тут синтаксис третьего питона. Для второго придётся чуть поменять со звёздочкой.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы