Использование itertools.groupby
:
>>> import itertools
>>> import operator
>>> foo = [("a", 1), ("a", 2), ("b", 1), ("c", 1), ("c", 2)]
>>> for group in itertools.groupby(foo, operator.itemgetter(0)):
... print group[0], list(map(operator.itemgetter(1), group[1]))
...
a [1, 2]
b [1]
c [1, 2]
Пояснение:
groupby
, как следует из названия, группирует элементы итерируемого в куски на основе некоторой ключевой функции. То есть он вызывает keyfunc
для первого элемента итерируемого, затем вытягивает элементы один за другим из итерируемого до тех пор, пока не изменится значение keyfunc
, после чего он возвращает все элементы, которые он получил, и начинает снова с новым ключом. Это также разумно и не потребляет больше памяти, чем необходимо; после получения значений они больше не удерживаются groupby
.
Здесь мы сгруппируем элементы ввода по operator.itemgetter(0)
, что является полезной функцией "toolbox", которая отображает x
в x[0]
. Другими словами, мы группируем по первому элементу кортежа, который является ключом.
Естественно, вам нужно написать собственный генератор для обработки чтения входных данных (с sys.stdin
, вероятно) и выдавать их один за другим. К счастью, это довольно просто, используя ключевое слово yield
.
Обратите внимание, что это предполагает, что ключи отсортированы. Естественно, если они не отсортированы, вы ничего не можете сделать: вам нужно посмотреть до конца ввода, чтобы убедиться, что у вас есть все значения для данного ключа.