[Python-ideas] Optional kwarg making attrgetter & itemgetter always return a tuple

Oscar Benjamin oscar.j.benjamin at gmail.com
Fri Sep 14 15:23:53 CEST 2012

On 14 September 2012 12:36, Masklinn <masklinn at masklinn.net> wrote:

> On 2012-09-14, at 13:01 , Nick Coghlan wrote:
> > On Thu, Sep 13, 2012 at 11:15 PM, Masklinn <masklinn at masklinn.net>
> wrote:
> >> attrgetter and itemgetter are both very useful functions, but both have
> >> a significant pitfall if the arguments passed in are validated but not
> >> controlled: if receiving the arguments (list of attributes, keys or
> >> indexes) from an external source and *-applying it, if the external
> >> source passes a sequence of one element both functions will in turn
> >> return an element rather than a singleton (1-element tuple).
> >
> > Both attrgetter and itemgetter are really designed to be called with
> > *literal* arguments, not via *args. In particular, they are designed
> > to be useful as arguments bound to a "key" parameter, where the object
> > vs singleton tuple distinction doesn't matter.
> It was my understanding that they are also designed to be useful for
> mapping (such a usage is shown in itemgetter's examples), which is
> a superset of the use case outlined here.
> > If that behaviour is not desirable, *write a different function* that
> > does what you want, and don't use itemgetter or attrgetter at all.
> > These tools are designed as convenience functions

I can see why you would expect different behaviour here, though. I tend not
to think of the functions in the operator module as convenience functions
but as *efficient* nameable functions referring to operations that are
normally invoked with a non-function syntax. Which is more convenient out
of the following:

1) using operator
import operator
result = sorted(values, key=operator.attrgetter('name'))

2) using lambda
result = sorted(values, key=lambda v: v.name)

I don't think that the operator module is convenient and I think that it
damages readability in many cases. My primary reason for choosing it in
some cases is that it is more efficient than the lambda expression.

There is no special syntax for 'get several items as a tuple'. I didn't
know about this extended use for attrgetter, itemgetter. I can't see any
other functions in the operator module (abs, add, and_, ...) that extend
the semantics of the operation they are supposed to represent in this way.

In general it is bad to conflate scalar/sequence semantics so that a caller
should get a different type of object depending on the length of a
sequence. I can see how practicality beats purity in adding this feature
for people who want to use these functions for sorting by a couple of
elements/attributes. I think it would have been better though to add these
as separate functions itemsgetter and attrsgetter that always return tuples.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20120914/c48a1cf3/attachment.html>

More information about the Python-ideas mailing list