Ответ 1
Используйте itertools.groupby:
import itertools
import operator
data=[(1, 'A', 'foo'),
(2, 'A', 'bar'),
(100, 'A', 'foo-bar'),
('xx', 'B', 'foobar'),
('yy', 'B', 'foo'),
(1000, 'C', 'py'),
(200, 'C', 'foo'),
]
for key,group in itertools.groupby(data,operator.itemgetter(1)):
print(list(group))
дает
[(1, 'A', 'foo'), (2, 'A', 'bar'), (100, 'A', 'foo-bar')]
[('xx', 'B', 'foobar'), ('yy', 'B', 'foo')]
[(1000, 'C', 'py'), (200, 'C', 'foo')]
Или, чтобы создать один список с каждой группой в качестве подписок, вы можете использовать понимание списка:
[list(group) for key,group in itertools.groupby(data,operator.itemgetter(1))]
Второй аргумент itertools.groupby
- это функция, которая itertools.groupby
применяется к каждому элементу в data
(первый аргумент). Ожидается, что он вернет key
. itertools.groupby
затем группирует все смежные элементы с тем же key
.
operator.itemgetter(1) выбирает второй элемент в последовательности.
Например, если
row=(1, 'A', 'foo')
затем
operator.itemgetter(1)(row)
равно 'A'
.
Как отмечает @eryksun в комментариях, если категории кортежей появляются в некотором случайном порядке, вы должны сначала отсортировать data
перед тем, как применить itertools.groupby
. Это связано с тем, что itertools.groupy
собирает смежные элементы с тем же ключом в группы.
Чтобы отсортировать кортежи по категориям, используйте:
data2=sorted(data,key=operator.itemgetter(1))