Advanced Dictionary

Discussion in 'Python' started by Thomas Lehmann, Jun 16, 2010.

  1. 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
    Thomas Lehmann, Jun 16, 2010
    #1
    1. Advertising

  2. >
    > 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())
    Thomas Lehmann, Jun 16, 2010
    #2
    1. Advertising

  3. Thomas Lehmann

    Peter Otten Guest

    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
    Peter Otten, Jun 16, 2010
    #3
  4. Thomas Lehmann

    Ian Kelly Guest

    On Wed, Jun 16, 2010 at 4:43 AM, Thomas Lehmann <> 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
    Ian Kelly, Jun 16, 2010
    #4
  5. 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/


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.10 (Darwin)

    iQEcBAEBAgAGBQJMGPkvAAoJEKcbwptVWx/lEy8H/2vmFntgOgfLUulBr/AbD1zc
    TBgFhrDRa7iqtB0BkGN4OrbTNlLtVy5hFyDkd0qgRBrYRYEJB67kCj0yrtmst3dy
    diVuQhylXGRNznNr60UETDpHl1eEA6XMkVj2Ou/uvdvzBPbGCw4sVvZJ1MyfeLXE
    LkWaMMvIcHJN5WzzGaEUws65AjXBXubrIecb+ahQ2Bx+KSqEFziP+hhV+cSMDH9X
    YIp/iKnhVccgZoVsGD3rvo4zPAMSNek3IEnE4gslLfdj/60CRuvhZnuRuIiBVifI
    IDcUri3B9XlotIP1otdNUaLWu9aYW7Vk/F2xIE1BoM5awMSLr0NGTmqry3kyEA0=
    =ZGp5
    -----END PGP SIGNATURE-----
    Stephen Hansen, Jun 16, 2010
    #5
  6. On Wed, 16 Jun 2010 09:17:47 -0700, Stephen Hansen wrote:

    > Leading-and-trailing double underscores are explicitly reserved for
    > Python to define as Special.



    That part is correct. But of course Python doesn't prevent you from
    ignoring this rule (more of a guideline really).



    > They also imply a slightly different
    > calling semantic: normal leading-and-trailing double underscore methods
    > bypass instance lookup.


    This is semi-correct. Operator overloading and other special method
    lookup bypasses instance lookup and calls type(instance).__method__ but
    that has nothing to do with the double-underscore methods themselves.
    They operate normally if you call them by hand:


    >>> class C(object):

    .... def __add__(self, other):
    .... return "special"
    ....
    >>> c = C()
    >>> c.__add__ = lambda self, other: "not very special"
    >>> c + 4

    'special'
    >>> c.__add__(c, 4)

    'not very special'


    --
    Steven
    Steven D'Aprano, Jun 16, 2010
    #6
  7. On 6/16/10 9:34 AM, Steven D'Aprano wrote:
    > On Wed, 16 Jun 2010 09:17:47 -0700, Stephen Hansen wrote:
    >
    >> Leading-and-trailing double underscores are explicitly reserved for
    >> Python to define as Special.

    >
    >
    > That part is correct. But of course Python doesn't prevent you from
    > ignoring this rule (more of a guideline really).


    Agreed. Its a namespace reserved for Python itself to define. But
    "reserved" in the more traditional Python sense of it saying, "Please
    keep your hands off", and not, "SyntaxError: Illegal creation of new
    special method".

    >> They also imply a slightly different
    >> calling semantic: normal leading-and-trailing double underscore methods
    >> bypass instance lookup.

    >
    > This is semi-correct. Operator overloading and other special method
    > lookup bypasses instance lookup and calls type(instance).__method__ but
    > that has nothing to do with the double-underscore methods themselves.
    > They operate normally if you call them by hand:


    Well, yes; I was simplifying slightly because people don't really call
    them by hand in the normal course of events (and eventually you'll pass
    the object into some internal where it most certainly doesn't get called
    that way).

    But true, that's more accurate. :)

    --

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


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.10 (Darwin)

    iQEcBAEBAgAGBQJMGQCYAAoJEKcbwptVWx/l5EIH/0bahUXbsxz8JKi6WulcXtXz
    qcJtcYyNrKk2tBwubd3aTLxjVYbUNna1nkuV2D3EZ48/4cEKJ7wc3Hhz7s1YXeYw
    B/5qjeoVg8jBfTQg9Y4Vlb3ZhuBGWIWyN7QYLf7qdNP6kSi6dZCVpHV8SoillrcK
    Y2+rbZ3UAQxDfgWWsVOSesQkKwGOZ10e79snBQw4lFIqlLKHEcfV3fIz4Z5meGtx
    mCZtOdCotW2ktnxMWgDQuD0NNKYMsEGb9P2vL6DjwCVTBSvpXt1Uw2g3Hu1E7nQH
    LcVRy1yduFcElryTyQmMf4i4KmDK0wNBvoIKaLEcbMs2jBY7v2YCox8vxcT7aW0=
    =qpXs
    -----END PGP SIGNATURE-----
    Stephen Hansen, Jun 16, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ilias Lazaridis
    Replies:
    6
    Views:
    438
    Ilias Lazaridis
    Feb 21, 2006
  2. james_027
    Replies:
    1
    Views:
    323
    Marc 'BlackJack' Rintsch
    Aug 22, 2007
  3. Michele Simionato
    Replies:
    1
    Views:
    595
    Lacrima
    Mar 27, 2010
  4. Navkirat Singh
    Replies:
    6
    Views:
    3,031
    Navkirat Singh
    Jul 29, 2010
  5. Chris Rebert
    Replies:
    0
    Views:
    522
    Chris Rebert
    Jul 29, 2010
Loading...

Share This Page