Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

295
Vistas
Set Python dict items recursively, when given a compound key 'foo.bar.baz'

I'd like to achieve the following:

foodict['foo.bar.baz'] = 'foo'
{
   'foo': {
      'bar': {
            'baz': 'foo'
         }
       }
   }
}

...creating keys recursively.

After scratching my head for a while, I've come up with this:

class Config(dict):
    def __init__(self, *args, **kwargs):
        self.super = super(Config, self)
        self.update(*args, **kwargs)

    def __setitem__(self, keys, value):
        keys   = keys.split('.')
        keys.reverse()

        config = Config()

        for i, k in enumerate(keys):
            if i == 0:
                config  = Config(**{ k: value })
            else:
                config  = Config(**{ k: config })

        self.super.update(config)
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

You might consider the "infinite defaultdict" recipe, from Raymond Hettinger himself:

https://twitter.com/raymondh/status/343823801278140417

>>> from collections import defaultdict
>>> infinite_defaultdict = lambda: defaultdict(infinite_defaultdict)
>>> d = infinite_defaultdict()
>>> d['foo']['bar']['baz'] = 'foo'
>>> d
defaultdict(<function <lambda> at 0x1040388c8>, {'foo': defaultdict(<function <lambda> at 0x1040388c8>, {'bar': defaultdict(<function <lambda> at 0x1040388c8>, {'baz': 'foo'})})})

Another option is to implement __missing__:

>>> class InfiniteDict(dict):
...     def __missing__(self, val):
...         d = InfiniteDict()
...         self[val] = d
...         return d
...
>>> d = InfiniteDict()
>>> d['foo']['bar']['baz'] = 'foo'
>>> d
{'foo': {'bar': {'baz': 'foo'}}}

And if you must have attribute access:

class InfiniteDict(dict):
   def __missing__(self, val):
       d = InfiniteDict()
       self[val] = d
       return d
   def __getattr__(self, item):
       return self.__getitem__(item)
   def __setattr__(self, item, value):
       super().__setitem__(item, value)

In action:

>>> d = InfiniteDict()
>>> d.foo.bar.baz = 'foo'
>>> d
{'foo': {'bar': {'baz': 'foo'}}}
>>>

Although, that's a little quick-and-dirty, so no guarantees there aren't any bugs. And there are very little guards against, for example, collisions with actual attributes:

>>> d.keys = 'should I be allowed?'
>>> d
{'foo': {'bar': {'baz': 'foo'}}, 'keys': 'should I be allowed?'}
>>> d.keys()
dict_keys(['foo', 'keys'])
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda