>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [(1,2), (1,6), (3,4), (3,6), (1,4), (4,3)]
>>> [[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
[[2, 4, 6], [4, 6], [3]]
Объяснение
Это работает с использованием itertools.groupby
. groupby
находит последовательных групп в итерабельном, возвращая итератор через ключ, группы пар.
Аргумент, присвоенный groupby
, является ключевой функцией itemgetter(0)
, которая вызывается для каждого кортежа, возвращая первый элемент в качестве ключа к groupby
.
groupby
группы элементов в их первоначальном порядке , так что если вы хотите, чтобы группа под первым номером в списке, то первый должен быть отсортирован так groupby
могут пройти первые числа в порядке возрастания и фактически группировать их.
>>> sorted(L)
[(1, 2), (1, 4), (1, 6), (3, 4), (3, 6), (4, 3)]
Существует отсортированный список, в котором вы можете четко видеть группы, которые будут созданы, если вы оглянетесь на конечный результат. Теперь вы можете использовать groupby
, чтобы показать ключи, группы.
[(1, <itertools._grouper object at 0x02BB7ED0>), (3, <itertools._grouper object at 0x02BB7CF0>), (4, <itertools._grouper object at 0x02BB7E30>)]
Здесь представлены отсортированные элементы, сгруппированные по первому номеру. groupby
возвращает группу для каждого ключа как итератора, это замечательно и очень эффективно, но для этого примера мы просто преобразуем его в list
, чтобы убедиться, что он работает правильно.
>>> [(k, list(v)) for k,v in groupby(sorted(L), itemgetter(0))]
[(1, [(1, 2), (1, 4), (1, 6)]), (3, [(3, 4), (3, 6)]), (4, [(4, 3)])]
Это почти правильная вещь, но требуемый вывод показывает только 2-е число в группах в каждом списке. Таким образом, достигается желаемый результат.
[[y for x, y in v] for k, v in groupby(sorted(L), itemgetter(0))]
Не уверен, что я понимаю, как ваш ввод относится к вашему выходу, не могли бы вы объяснить немного больше? – Levon
это еще не имеет значения – wim