119 votes

Existe-t-il un moyen intelligent de passer la clé de defaultdict' s default_factory ?

Une classe a un constructeur qui prend un paramètre :

class C(object):
    def __init__(self, v):
        self.v = v
        ...

Quelque part dans le code, il est utile que les valeurs d'une dictée connaissent leurs clés.
Je veux utiliser un décret par défaut avec la clé passée aux valeurs par défaut du nouveau-né :

d = defaultdict(lambda : C(here_i_wish_the_key_to_be))

Des suggestions ?

168voto

Jochen Ritzel Points 42916

Cela ne se qualifie guère comme intelligent - mais la sous-classe est votre ami :

class keydefaultdict(defaultdict):
    def __missing__(self, key):
        if self.default_factory is None:
            raise KeyError( key )
        else:
            ret = self[key] = self.default_factory(key)
            return ret

d = keydefaultdict(C)
d[x] # returns C(x)

2voto

gerardw Points 330

Voici un exemple pratique d'un dictionnaire qui ajoute automatiquement une valeur. La tâche de démonstration dans la recherche de fichiers en double dans /usr/include. Note de personnalisation du dictionnaire PathDict ne nécessite que quatre lignes :

class FullPaths:

    def __init__(self,filename):
        self.filename = filename
        self.paths = set()

    def record_path(self,path):
        self.paths.add(path)

class PathDict(dict):

    def __missing__(self, key):
        ret = self[key] = FullPaths(key)
        return ret

if __name__ == "__main__":
    pathdict = PathDict()
    for root, _, files in os.walk('/usr/include'):
        for f in files:
            path = os.path.join(root,f)
            pathdict[f].record_path(path)
    for fullpath in pathdict.values():
        if len(fullpath.paths) > 1:
            print("{} located in {}".format(fullpath.filename,','.join(fullpath.paths)))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X