[Python-ideas] Add "default" kw argument to operator.itemgetter and operator.attrgetter

Steven D'Aprano steve at pearwood.info
Tue May 8 06:17:32 EDT 2018

On Tue, May 08, 2018 at 10:13:43AM +0200, Vincent Maillol wrote:

> Perhaps something like:
> >
> > >>> itemgetter(-1, 0, -2,
> > ...            default0="first argument default",
> > ...            default1=["second", "argument", "default"],
> > ...            default={"global": "default"},
> > ... )

Sorry Vincent, but I think that's precisely the sort of overly 
complicated API that Raymond was worried about when he voted against 
this proposal. A single default value that applies when the item (or 
key) isn't present is easy to comprehend. But this extention is, I 
think, a case of an over-engineered, excessively intricate solution, 
and I doubt it solves any real problem.

And I'm not even sure I know what it means. You have keyword parameters 
default0, default1, and then *default* with no suffix. Is that a typo 
for default2, or is it supposed to be a default default, the default to 
use when no default is specified?

> The keywords suffixed by indice are uncommon. Maybe we can use dedicated
> object.
> >>> itemgetter(
> ...     itemgetter.WithDefault(-1, "first argument default"),
> ...     itemgetter.WithDefault(0, ["second", "argument", "default"])
> ...     -2  # has no default value
> ... )

I'm afraid there's no elegance to this design either.

I've had many occasions where I want to get an item, falling back on a 
default if it is not present. With dicts this is common enough that we 
have dict.get(). It is less convenient with lists, and I'd like to see 
itemgetter support that case.

But I cannot think of any case where I have needed or wanted to extract

    item 5 with "spam" as the default
    item 2 with no default
    item 3 with "eggs" as the default

(for example), let alone that this is *so common* that I'd rather read 
the complicated documenation to work out how to use the function, rather 
than just write a short helper:

def extract(sequence):
    return ("spam" if len(sequence) < 5 else sequence[5],
            "eggs" if len(sequence) < 5 else sequence[3],

Raymond and Serhey are right: beyond a certain point, we should just 
write a custom function (whether lambda or not). We just disagree on 
which side of that point the single-default value case is, but I think 
we will agree that your example is so far past the point that we cannot 
even see it from here :-)


More information about the Python-ideas mailing list