On Sun, 16 Jul 2023 at 04:07, Jothir Adithyan <adithyanjothir@gmail.com> wrote:
Chris Angelico 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
On Tue, 11 Jul 2023 at 08:05, Jothir Adithyan adithyanjothir@gmail.com wrote: 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 Hey Chris, thank you for your time and insight.
I've thought about this for some time, and I believe that adding this feature could indeed be a useful and concise helper for many Python users, especially for API integrations and web scraping where encountering None values is quite common. Do you think it would be feasible to modify the existing get function to include a new parameter or perhaps introduce a new function altogether?
I'm trying to understand why this idea may not be considered favorable. What are the reasons for not having this feature? What makes the current approach better than having this additional functionality?
The reason it's not a good fit for the language itself is that there are lots of small variations. I gave you one other slight variant in my example, and there are myriad other small differences that could show up. So it's best for it to be part of your own toolkit. I would strongly recommend giving the "path lookup" function style a try; it's actually way more expressive than chained lookups, in the situations that it's appropriate to. ChrisA