From: Thomas Lehmann on
Hi,

I have seen a recipe which allows auto creation of missing values for
dictionaries.
However this recipe is not working for all.

class AutoValueDict(dict):
def __makeitem__(self, key):
return self.setdefault(key, {})

def __getitem__(self, key):
return self.get(key, self.__makeitem__(key))

I would like to have a dictionary which ensures dictionaries as values
except when I'm assigning another:

dict["abc"]["xyz"]["123"]["456"] = 123

How can I do this without many "if" and "else"?

best regards
Thomas
From: Thomas Lehmann on
>
> class AutoValueDict(dict):
>     def __makeitem__(self, key):
>         return self.setdefault(key, {})
>
>     def __getitem__(self, key):
>         return self.get(key, self.__makeitem__(key))
>
> I would like to have a dictionary which ensures dictionaries as values
> except when I'm assigning another:
>
> dict["abc"]["xyz"]["123"]["456"] = 123
>
> How can I do this without many "if" and "else"?
>

Oh no... of course like this:
return self.setdefault(key, AutoValueDict())

From: Peter Otten on
Thomas Lehmann wrote:

>> class AutoValueDict(dict):
>> def __makeitem__(self, key):
>> return self.setdefault(key, {})

I think it's bad style to invent your own __whatever__() methods, I'd rather
call them _whatever().

>> def __getitem__(self, key):
>> return self.get(key, self.__makeitem__(key))
>>
>> I would like to have a dictionary which ensures dictionaries as values
>> except when I'm assigning another:
>>
>> dict["abc"]["xyz"]["123"]["456"] = 123
>>
>> How can I do this without many "if" and "else"?
>>
>
> Oh no... of course like this:
> return self.setdefault(key, AutoValueDict())
>

An alternative implementation (requires Python 2.5):

>>> class A(dict):
.... def __missing__(self, key):
.... print "creating subdict for", key
.... value = A()
.... self[key] = value
.... return value
....
>>> a = A()
>>> a["x"]["y"]["z"] = 42
creating subdict for x
creating subdict for y
>>> a
{'x': {'y': {'z': 42}}}

Peter
From: Ian Kelly on
On Wed, Jun 16, 2010 at 4:43 AM, Thomas Lehmann <t.lehmann(a)rtsgroup.net> wrote:
> Hi,
>
> I have seen a recipe which allows auto creation of missing values for
> dictionaries.
> However this recipe is not working for all.
>
> class AutoValueDict(dict):
>    def __makeitem__(self, key):
>        return self.setdefault(key, {})
>
>    def __getitem__(self, key):
>        return self.get(key, self.__makeitem__(key))
>
> I would like to have a dictionary which ensures dictionaries as values
> except when I'm assigning another:
>
> dict["abc"]["xyz"]["123"]["456"] = 123
>
> How can I do this without many "if" and "else"?

Why not use defaultdict?

from collections import defaultdict

def recursive_defaultdict():
return defaultdict(recursive_defaultdict)

my_dict = recursive_defaultdict()
my_dict["abc"]["xyz"]["123"]["456"] = 123

Cheers,
Ian
From: Stephen Hansen on
On 6/16/10 6:10 AM, Peter Otten wrote:
> Thomas Lehmann wrote:
>
>>> class AutoValueDict(dict):
>>> def __makeitem__(self, key):
>>> return self.setdefault(key, {})
>
> I think it's bad style to invent your own __whatever__() methods, I'd rather
> call them _whatever().

It goes a bit beyond bad style into, "it is explicitly forbidden", I think.

Not that "forbidden" means, "Python will prevent you from trying", just
that it says, "Don't do it."

Leading-and-trailing double underscores are explicitly reserved for
Python to define as Special. They also imply a slightly different
calling semantic: normal leading-and-trailing double underscore methods
bypass instance lookup.

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/