Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Re-tri d'une liste groupée

+3 votes

En résumé : pourquoi ce code ne marche pas ?

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4 nu

from itertools import groupby

l = [1, 2, 3, 4, 5, 6, 1]

l = sorted(l, key=lambda x: x)
numbers = groupby(l, key=lambda x: x)
numbers2 = sorted(numbers, key=lambda (x,y): x)

print(numbers)
print(numbers2)

for k, n in numbers2:
    print(list(n))

Qu'est-ce qui fait que au niveau du second sorted on perd des éléments dans les sous-listes ?

En pratique, j'ai évidemment un exemple un peu plus utile. C'est dans le cadre d'une interface de supervision, j'ai une liste de services que je tri par serveur pour ensuite les groupby par serveur. Mais cette liste de serveurs (avec leurs listes de services), j'ai besoin de la re-trier par criticité (et non plus par ordre alphabétique du nom de serveur). Et je n'y arrive pas.

demandé 28-Mai-2015 par maethor (150 points)
rouvert 29-Mai-2015 par boblinux

je pense que l'utilisation du groupby est foireuse

Qui a fermé la question?
Le fait qu'une réponse ait été trouvée ne signifie pas que c'est la meilleur réponse possible, ça signifie juste que l'auteur de la question a trouvé ce qu'il cherchait. Mais il ne faudrait pas privé d'autres lecteurs qui pourraient passer par là et chercher une autre réponse possible qui conviendrait mieux à leur problème...
Je peux la ré-ouvrir si besoin *

D'un coté du me dit de fermer la question, et de l'autre tu me dis qu'il fallait pas ?

Il y a eu un mal-entendu lol, je voulais juste dire que tu peux désigner la meilleur réponse désolé ;p.

mettre le post en résolu
signifie juste désigner ta meilleur réponse =D

J'ai ré-ouvert la question

2 Réponses

+3 votes
 
Meilleure réponse

Pas de réponse à ma propre question, mais j'ai trouvé un workaround :

numbers = [(k, list(v)) for k, v in groupby(l, key=lambda x: x)]

C'est un peu crado, mais je ne pense pas avoir d'autre choix.

répondu 28-Mai-2015 par maethor (150 points)
sélectionné 28-Mai-2015 par maethor
+1 vote

Qu'on soit bien d'accord sur ce point, le group by fonctionne comme ceci :

>>> for k, g in groupby('AAAABBBCCDAABBB'):
...     print(k)
... 
A
B
C
D
A
B

>>> for k, g in groupby('AAAABBBCCD'):
...     print(list(g))
... 
['A', 'A', 'A', 'A']
['B', 'B', 'B']
['C', 'C']
['D']

Donc un code (se servant de groupby + sorted) tournerait comme cela :

groups = []
uniquekeys = []
data = sorted(data, key=keyfunc)
for k, g in groupby(data, keyfunc):
    groups.append(list(g))      # Store group iterator as a list
    uniquekeys.append(k)
répondu 28-Mai-2015 par boblinux (3,092 points)

Oui, mais ma question n'est pas sur l'usage de base d'un groupby. Ce que je cherche à faire c'est le retrier avant de l'utiliser.

Tu veux obtenir quel résultat en gros??
Car sans exemple on n'ira pas très loin ;)

C'est pas vraiment une question de résultat, mais de pourquoi le second sorted consomme les sous-iterateurs. En fait, j'ai trouvé pourquoi : https://docs.python.org/2/library/itertools.html#itertools.groupby

The returned group is itself an iterator that shares the underlying iterable with groupby(). Because the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be stored as a list:

Donc oui, ta réponse est bonne. La mienne aussi. Pour que ça marche, il faut forcément "caster" les iterateurs en listes à la sortie du groupby, sinon le sorted les consomme.

Cool, t'as plu qu'à traduire ton pavé, mettre le post en résolu et éditer le post avec les réponses =D
(Je sais...je sais... je t'en demande trop ! ;p )

...