dict.get_deep()
Marco Sulla
Marco.Sulla.Python at gmail.com
Sun Apr 3 17:17:04 EDT 2022
On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer <hjp-python at hjp.at> wrote:
>
> > > data.get_deep("users", 0, "address", "street", default="second star")
>
> Yep. Did that, too. Plus pass the final result through a function before
> returning it.
I didn't understand. Have you added a func parameter?
> I'm not sure whether I considered this when I wrote it, but a function
> has the advantage of working with every class which can be indexed. A
> method must be implemented on any class (so at least dict and list to be
> useful).
You're right, but where to put it? I don't know if an iterableutil package
exists. If included in the stdlib, I don't know where to put it. In
collections maybe?
PS: if you're interested, here is my implementation:
def get_deep(self, *args, default=_sentinel):
r"""
Get a nested element of the dictionary.
The method accepts multiple arguments or a single one. If a single
argument is passed, it must be an iterable. This represents the
keys or indexes of the nested element.
The method first tries to get the value v1 of the dict using the
first key. If it finds v1 and there's no other key, v1 is
returned. Otherwise, the method tries to retrieve the value from v1
associated with the second key/index, and so on.
If in any point, for any reason, the value can't be retrieved, the
`default` parameter is returned if specified. Otherwise, a
KeyError or an IndexError is raised.
"""
if len(args) == 1:
single = True
it_tpm = args[0]
try:
len(it_tpm)
it = it_tpm
except Exception:
# maybe it's a generator
try:
it = tuple(it_tpm)
except Exception:
err = (
f"`{self.get_deep.__name__}` called with a single " +
"argument supports only iterables"
)
raise TypeError(err) from None
else:
it = args
single = False
if not it:
if single:
raise ValueError(
f"`{self.get_deep.__name__}` argument is empty"
)
else:
raise TypeError(
f"`{self.get_deep.__name__}` expects at least one argument"
)
obj = self
for k in it:
try:
obj = obj[k]
except (KeyError, IndexError) as e:
if default is _sentinel:
raise e from None
return default
return obj
More information about the Python-list
mailing list