Utilisation 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]
Explication:
groupby
, comme son nom l'indique, des éléments de groupes d'un itérable en morceaux basés sur une fonction clé. C'est-à-dire, il appelle keyfunc
sur le premier élément de l'itératif, puis tire les éléments un par un de l'itératif jusqu'à ce que la valeur de keyfunc
change, à ce point il cède tous les éléments qu'il a jusqu'ici et recommence depuis le nouveau clé. Il est également sensible et ne consomme pas plus de mémoire que nécessaire; Une fois que les valeurs ont été cédées, elles ne sont plus détenues par groupby
.
Ici, nous regroupons les éléments de l'entrée par operator.itemgetter(0)
, qui est une fonction "boîte à outils" utile qui mappe x
à x[0]
. En d'autres termes, nous groupons par le premier élément du tuple, qui est une clé.
Naturellement, vous aurez besoin d'écrire un générateur personnalisé pour gérer la lecture de l'entrée (de sys.stdin
, probablement) et les céder un par un. Heureusement, c'est assez facile, en utilisant le mot-clé yield
.
Notez également que cela suppose que les clés sont triées. Naturellement, s'ils ne sont pas triés, il n'y a rien que vous puissiez faire: vous devrez regarder jusqu'à la fin de l'entrée pour vous assurer que vous avez toutes les valeurs pour une clé donnée.