Je n'ai pas pu trouver d'explication compréhensible sur la façon d'utiliser réellement la itertools.groupby()
fonction de Python . Ce que j'essaie de faire, c'est ceci:
- Prenez une liste - dans ce cas, les enfants d'un
lxml
élément objectivé - Divisez-le en groupes en fonction de certains critères
- Ensuite, parcourez séparément chacun de ces groupes.
J'ai examiné la documentation et les exemples , mais j'ai eu du mal à les appliquer au-delà d'une simple liste de chiffres.
Alors, comment puis-je utiliser itertools.groupby()
? Y a-t-il une autre technique que je devrais utiliser? Des pointeurs vers une bonne lecture «préalable» seraient également appréciés.
Réponses:
REMARQUE IMPORTANTE: vous devez d'abord trier vos données .
La partie que je n'ai pas obtenue est que dans l'exemple de construction
k
est la clé de regroupement actuelle etg
est un itérateur que vous pouvez utiliser pour itérer sur le groupe défini par cette clé de regroupement. En d'autres termes, legroupby
itérateur lui-même renvoie des itérateurs.Voici un exemple de cela, en utilisant des noms de variables plus clairs:
Cela vous donnera la sortie:
Dans cet exemple,
things
est une liste de tuples où le premier élément de chaque tuple est le groupe auquel appartient le deuxième élément.La
groupby()
fonction prend deux arguments: (1) les données à grouper et (2) la fonction à grouper avec.Ici,
lambda x: x[0]
indiquegroupby()
d'utiliser le premier élément de chaque tuple comme clé de regroupement.Dans la
for
déclaration ci-dessus ,groupby
renvoie trois paires (clé, itérateur de groupe) - une fois pour chaque clé unique. Vous pouvez utiliser l'itérateur renvoyé pour parcourir chaque élément individuel de ce groupe.Voici un exemple légèrement différent avec les mêmes données, utilisant une compréhension de liste:
Cela vous donnera la sortie:
la source
groupby(sorted(my_collection, key=lambda x: x[0]), lambda x: x[0]))
en supposant quemy_collection = [("animal", "bear"), ("plant", "cactus"), ("animal", "duck")]
et que vous souhaitez regrouper paranimal or plant
L'exemple sur les documents Python est assez simple:
Donc, dans votre cas, les données sont une liste de nœuds,
keyfunc
c'est là que va la logique de votre fonction de critères, puisgroupby()
regroupe les données.Vous devez être prudent de trier les données selon les critères avant d'appeler
groupby
ou cela ne fonctionnera pas.groupby
En fait, la méthode parcourt simplement une liste et chaque fois que la clé change, elle crée un nouveau groupe.la source
keyfunc
et vous avez dit "ouais, je sais exactement ce que c'est parce que cette documentation est assez simple."? Incroyable!itertools.groupby
est un outil pour regrouper des éléments.À partir des documents , nous glanons plus loin ce qu'il pourrait faire:
groupby
les objets produisent des paires de groupes de clés où le groupe est un générateur.Caractéristiques
Comparaisons
Les usages
Remarque: Plusieurs de ces derniers exemples proviennent du PyCon (discours) de Víctor Terrón (espagnol) , "Kung Fu at Dawn with Itertools". Voir aussi le
groupby
code source écrit en C.* Une fonction où tous les éléments sont passés et comparés, influençant le résultat. D'autres objets avec des fonctions clés incluent
sorted()
,max()
etmin()
.Réponse
la source
[''.join(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
.list()
,tuple()
) ou consommés dans une boucle / compréhension pour afficher le contenu. Ce sont des redondances que l'auteur a probablement exclues pour économiser de l'espace.Une astuce intéressante avec groupby consiste à exécuter le codage de longueur sur une seule ligne:
vous donnera une liste de 2-tuples où le premier élément est le caractère et le 2e est le nombre de répétitions.
Edit: Notez que c'est ce qui sépare
itertools.groupby
de laGROUP BY
sémantique SQL : itertools ne trie pas (et en général ne peut pas) l'itérateur à l'avance, donc les groupes avec la même "clé" ne sont pas fusionnés.la source
Un autre exemple:
résulte en
Notez que igroup est un itérateur (un sous-itérateur comme l'appelle la documentation).
Ceci est utile pour découper un générateur:
Un autre exemple de groupby - lorsque les clés ne sont pas triées. Dans l'exemple suivant, les éléments de xx sont regroupés par valeurs en yy. Dans ce cas, un ensemble de zéros est émis en premier, suivi d'un ensemble de uns, suivi à nouveau par un ensemble de zéros.
Produit:
la source
ATTENTION:
La liste de syntaxe (groupby (...)) ne fonctionnera pas comme vous le souhaitez. Il semble détruire les objets internes de l'itérateur, donc en utilisant
produira:
Au lieu de list (groupby (...)), essayez [(k, list (g)) pour k, g dans groupby (...)], ou si vous utilisez souvent cette syntaxe,
et accéder à la fonctionnalité groupby tout en évitant tous ces itérateurs gênants (pour les petites données).
la source
Je voudrais donner un autre exemple où groupby sans tri ne fonctionne pas. Adapté de l'exemple de James Sulak
la sortie est
il y a deux groupes avec véhicule, alors que l'on ne peut s'attendre qu'à un seul groupe
la source
@CaptSolo, j'ai essayé votre exemple, mais cela n'a pas fonctionné.
Production:
Comme vous pouvez le voir, il y a deux o et deux e, mais ils sont entrés dans des groupes séparés. C'est alors que j'ai réalisé que vous devez trier la liste transmise à la fonction groupby. Ainsi, l'utilisation correcte serait:
Production:
N'oubliez pas que si la liste n'est pas triée, la fonction groupby ne fonctionnera pas !
la source
la source
Vous pouvez utiliser groupby pour regrouper des éléments sur lesquels itérer. Vous donnez à groupby un itérable et une fonction clé / appelable facultative permettant de vérifier les éléments lorsqu'ils sortent de l'itérable, et il renvoie un itérateur qui donne deux fois le résultat de la clé appelable et les éléments réels dans un autre itérable. De l'aide:
Voici un exemple de groupby utilisant une coroutine pour regrouper par un nombre, il utilise une clé appelable (dans ce cas,
coroutine.send
) pour simplement cracher le nombre pour autant d'itérations et un sous-itérateur groupé d'éléments:impressions
la source
Un exemple utile que j'ai rencontré peut être utile:
Exemple d'entrée: 14445221
Exemple de sortie: (1,1) (3,4) (1,5) (2,2) (1,1)
la source
Cette implémentation de base m'a aidé à comprendre cette fonction. J'espère que cela aide aussi les autres:
la source
Vous pouvez écrire votre propre fonction groupby:
la source