Étant donné une liste
old_list = [obj_1, obj_2, obj_3, ...]
Je veux créer une liste:
new_list = [[obj_1, obj_2], [obj_3], ...]
où obj_1.some_attr == obj_2.some_attr
.
Je pourrais lancer des boucles for
et des contrôles if
ensemble, mais c'est moche. Existe-t-il un moyen Pythonique pour cela? au fait, les attributs des objets sont tous des chaînes.
Alternativement, une solution pour une liste contenant des tuples (de la même longueur) au lieu d'objets est également appréciée.
defaultdict
est la façon dont cela se fait.
Alors que les boucles for
sont largement essentielles, les instructions if
ne le sont pas.
from collections import defaultdict
groups = defaultdict(list)
for obj in old_list:
groups[obj.some_attr].append(obj)
new_list = groups.values()
Voici deux cas. Les deux nécessitent les importations suivantes:
import itertools
import operator
Vous utiliserez itertools.groupby et operator.attrgetter ou operator.itemgetter .
Pour une situation où vous regroupez par obj_1.some_attr == obj_2.some_attr
:
get_attr = operator.attrgetter('some_attr')
new_list = [list(g) for k, g in itertools.groupby(sorted(old_list, key=get_attr), get_attr)]
Pour a[some_index] == b[some_index]
:
get_item = operator.itemgetter(some_index)
new_list = [list(g) for k, g in itertools.groupby(sorted(old_list, key=get_item), get_item)]
Notez que vous avez besoin du tri car itertools.groupby
crée un nouveau groupe lorsque la valeur de la clé change.
Notez que vous pouvez l'utiliser pour créer un dict
comme la réponse de S.Lott, mais ne devez pas utiliser collections.defaultdict
.
Utiliser une compréhension de dictionnaire (ne fonctionne qu'avec Python 3+, et éventuellement Python 2.7 mais je ne suis pas sûr)):
groupdict = {k: g for k, g in itertools.groupby(sorted_list, keyfunction)}
Pour les versions précédentes de Python, ou comme alternative plus succincte:
groupdict = dict(itertools.groupby(sorted_list, keyfunction))
Pensez que vous pouvez également essayer d'utiliser itertools.groupby . Veuillez noter que le code ci-dessous n'est qu'un exemple et doit être modifié en fonction de vos besoins:
data = [[1,2,3],[3,2,3],[1,1,1],[7,8,9],[7,7,9]]
from itertools import groupby
# for example if you need to get data grouped by each third element you can use the following code
res = [list(v) for l,v in groupby(sorted(data, key=lambda x:x[2]), lambda x: x[2])]# use third element for grouping