Comments on: Compter et grouper : encore plus fainéant http://sametmax.com/compter-et-grouper-encore-plus-faineant/ Du code, du cul Fri, 06 Sep 2019 09:34:15 +0000 hourly 1 https://wordpress.org/?v=4.9.7 By: Seb http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-164715 Sun, 04 Oct 2015 14:02:16 +0000 http://sametmax.com/?p=16529#comment-164715 Complément (intéressant ?) à l’article (il s’agit d’une sorte de généralisation du Grouper de l’article).

J’avais besoin de grouper les éléments d’une liste selon certains critères. Par exemple, mettons que j’ai une liste d’objets qui ont comme attributs “name”, “age”, et “city” (plus d’autres trucs) ; j’ai envie de récupérer un dico qui soit “trié” selon ces trois critères ; par exemple pour avoir :

 
{
     'sam' : { # tous les "sam"
        5: { # qui ont 5 ans
            'Paris': [ , ], #qui habitent Paris
            'Nantes': [, ]
       },
       7: { #tous les sams qui ont 7 ans
             'Paris' : [object5],
            'Tokyo': [object6, object7] # qui habitent Tokyo
      }
}

J’ai donc créé une classe qui s’utilise de la manière suivante:


# on définit nos clefs de tri

key_name = lambda x: x.name

key_age = lambda x: x.age

key_city = lambda x: x.city

# objects contient tous les objets que je veux ordonner

organized_dico = Organizer(objects, (f1, f2, f3))

# on peut classer selon la vile d'abord si on veut:

organized_dico2 = Organizer(objects, (f3, f1, f2))

Et voici le code de la classe, en gros il s’agit d’un defaultdict “récursif” dont tous les niveaux sont eux même des defaultdict et le dernier est une liste. À chaque ajout d’un élément, on évalue successivement les différents sort_keys pour savoir où placer cet élément dans la structure :

from collections import defaultdict

class Organizer(defaultdict):

    def __init__(self, iterable=tuple(), sort_keys=tuple()):
        super(Organizer, self).__init__(Organizer)
        self.sort_keys = sort_keys
        self.update(iterable)

    def update(self, iterable):
        for item in iterable:
            current_dict = self
            for key in self.sort_keys[:-1]:
                current_dict = current_dict[key(item)] 
            slot = current_dict[self.sort_keys[-1](item)]
            if slot:
                slot.append(item)
            else:
                current_dict[self.sort_keys[-1](item)] = [item]

Je ne suis pas pleinement satisfait par ma gestion du dernier niveau de récursion… Des idées pour faire un truc plus clean ?

]]>
By: boblinux http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-162882 Thu, 02 Jul 2015 23:27:26 +0000 http://sametmax.com/?p=16529#comment-162882 Eso sí que es buena .

Artículo sobresaliendo como de costumbre ;)

]]>
By: Sam http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-162852 Thu, 02 Jul 2015 07:35:06 +0000 http://sametmax.com/?p=16529#comment-162852 He actualizado el artículo. Hay algo que no me visto ?

]]>
By: boblinux http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-162837 Wed, 01 Jul 2015 23:57:30 +0000 http://sametmax.com/?p=16529#comment-162837 @Darkxxx

Me has mordido!

Acabo de notar al leer el artículo, al parecer, el Tío @Sam aún no ha actualizado .

PS : Bueno, yo entiendo su reactividad , es 02 a.m. a Francia

]]>
By: Sam http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-162832 Wed, 01 Jul 2015 22:21:52 +0000 http://sametmax.com/?p=16529#comment-162832 Si senor.

]]>
By: DarkNihilius http://sametmax.com/compter-et-grouper-encore-plus-faineant/#comment-162827 Wed, 01 Jul 2015 20:56:17 +0000 http://sametmax.com/?p=16529#comment-162827

>>> c = Counter("aabbbbbbbbbbbbcccc")

>>> c & Counter('aaaaaaaaaaaaaaabbcddddddd') # valeurs min

Counter({'b': 2, 'a': 2, 'c': 1})

>>> c | Counter('aaaaaaaaaaaaaaabbcddddddd') # valeurs max

Counter({'a': 15, 'b': 12, 'd': 7, 'c': 4})

UN petit soucis d’encodage non ? (et une petite typo en prime)

]]>