On Tue, 11 Jul 2023 at 08:05, Jothir Adithyan <adithyanjot...@gmail.com> wrote:
> Assumptions:
>
> The problem statement is based on a few assumptions:
> - You prefer chaining `get` statements for cleaner code.
> - You expect at least some of the `get` methods to return `None`.
> - You want to avoid the hassle of using `try` and `except` for every `get` 
> chain.
>

The main assumption here is that None is a perfectly valid value in
your data, and should be equivalent to the key being omitted. I think
this is uncommon enough to be better done with custom code. But
fortunately, there's a really cool way to write that custom code, and
that's a path lookup - this is a sort of function that I've written in
a lot of these situations. Using your examples:

> import contextlib
> parent_dict = PlayDict()
> parent_dict['k1'] = None
> parent_dict['k2'] = {"child_key": "val"} # Parent dict can contain nested 
> dicts
>
> with contextlib.suppress(AttributeError):
>     result = parent_dict.get("k1", {}).get("child_key") # This will raise 
> AttributeError
>
> result = parent_dict.get_or("k1", default={}, arbitrary={}).get("child_key") 
> # This will work
>

I'd write it like this:

def lookup(basis, *keys, default=None):
    for key in keys:
        basis = basis.get(key)
        if basis is None: return default
    return basis

result = lookup(parent_dict, "k1", "child_key")

This quite tidily expresses the intent ("delve into this dictionary
and follow this path, returning None if there's nothing there"), and
is compact, with no repetition. It's a relatively short helper
function too, and easy to change into other forms. For example, here's
another version that I use, which guarantees to always return a
dictionary:

def lookup(basis, *keys):
    for key in keys:
        if key not in basis: basis[key] = {}
        basis = basis[key]
    return basis

Etcetera. Flexible and very handy.

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/UIIRM2KIRBUMGHKKZNUU233WWOLSUXIB/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to