itemgetter with default arguments

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri May 4 09:01:44 EDT 2018


A re-occurring feature request is to add a default to itemgetter and 
attrgetter. For example, we might say:

from operator import itemgetter
f = itemgetter(1, 6, default="spam")  # proposed feature
f("Hello World!")  # returns ('e', 'W')
f("Hello")         # returns ('e', 'spam')


Two senior developers have rejected this feature, saying that we should 
just use a lambda instead.

I might be slow today, but I cannot see how to write a clear, obvious, 
efficient lambda that provides functionality equivalent to itemgetter 
with a default value.

Putting aside the case where itemgetter takes multiple indexes, how about 
the single index case? How could we get that functionality using a lambda 
which is simple and obvious enough to use on the fly as needed, and 
reasonably efficient?

Here are the specifications:

* you must use lambda, not def;

* the lambda must take a single function, the sequence you want to
  extract an item from;

* you can hard-code the index in the body of the lambda;

* you can hard-code the default value in the body of the lambda;

* if sequence[index] exists, return that value;

* otherwise return the default value;

* it should support both positive and negative indices.

Example: given an index of 2 and a default of "spam":

    (lambda seq: ... )("abcd") returns "c"

    (lambda seq: ... )("") returns "spam"


I might be missing something horribly obvious, but I can't see how to do 
this using a lambda. I tried using slicing:

    seq[index:index+1]

which will return either an empty slice or a one-item slice, but that 
didn't help me. I feel I'm missing something either obvious, or something 
impossible, and I don't know which.

(This isn't a code-golf problem. I care more about being able to do it at 
all, than about doing it in the minimum number of characters.)



-- 
Steve




More information about the Python-list mailing list