Generic dictionary

Steve D'Aprano steve+python at pearwood.info
Sun Nov 20 06:40:19 EST 2016


Further thoughts come to mind, after looking more closely at your code.

On Sun, 20 Nov 2016 08:27 pm, Thorsten Kampe wrote:

> class GenericDict:
>     """
>     a GenericDict is a dictionary or a list of tuples (when the keys
>     are not hashable)
>     """
>     def __init__(inst, generic_dict):
>         inst._generic = generic_dict
> 
>     def __getitem__(inst, key):
>         if isinstance(inst._generic, dict):
>             return inst._generic[key]
>         else:
>             return inst.values()[inst.keys().index(key)]

Your code seems to be different from your description. Rather than
*behaving* like a list of (key, item) pairs, you seem to actually have
something which always behaves like a dict, but has a different internal
storage. That's less disturbing than what I thought you wanted at first.

There's probably a "Design Pattern" name for this sort of thing: a
consistent front end, with a different back end for storage. But I guess it
is overkill for here, and besides, using a list of (key, item) is not going
to be an efficient back end storage. Oh, it will be fine if you have ten or
a hundred items, but if you have a million, it will be painful.

Better to just use a dict, always, and simply convert any list of tuples to
a dict:

py> dict([('a', 1), ('b', 2), ('c', 3)])
{'c': 3, 'a': 1, 'b': 2}


>     def values(inst):
>         if isinstance(inst._generic, dict):
>             return inst._generic.values()
>         else:
>             try:
>                 return list(zip(*inst._generic))[1]
>             except IndexError:  # empty GenericDict
>                 return ()

That's... weird. Sometimes your instance will return a list, and sometimes a
tuple. So if you write code expecting a list, it will suddenly and
unexpectedly break when the instance is empty.

A better way of writing this is:

    def values(inst):
        if isinstance(inst._generic, dict):
            return inst._generic.values()
        else:
            return [t[1] for t in inst._generic]

(But even better is not to write it at all, and just use the dict, like I
suggested above :-)





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list