<p>On Sep 14, 2012 10:02 PM, "Jim Jewett" <<a href="mailto:jimjjewett@gmail.com">jimjjewett@gmail.com</a>> wrote:<br>
><br>
> On 9/14/12, Oscar Benjamin <<a href="mailto:oscar.j.benjamin@gmail.com">oscar.j.benjamin@gmail.com</a>> wrote:<br>
><br>
> > I can see why you would expect different behaviour here, though. I tend not<br>
> > to think of the functions in the operator module as convenience functions<br>
> > but as *efficient* nameable functions referring to operations that are<br>
> > normally invoked with a non-function syntax. Which is more convenient out<br>
> > of the following:<br>
><br>
> > 1) using operator<br>
> > import operator<br>
> > result = sorted(values, key=operator.attrgetter('name'))<br>
><br>
> I would normally write that as<br>
><br>
>     from operator import attrgetter as attr<br>
>     ... # may use it several times<br>
><br>
>     result=sorted(values, key=attr('name'))<br>
><br>
> which is about the best I could hope for, without being able to use<br>
> the dot itself.</p>
<p>To be clear, I wasn't complaining about the inconvenience of importing and referring to attrgetter. I was saying that if the obvious alternative (lambda functions) is at least as convenient then it's odd to describe itemgetter/attrgetter as convenience functions.</p>

<p>> > 2) using lambda</p>
<p>> > result = sorted(values, key=lambda v: <a href="http://v.name">v.name</a>)<br>
><br>
> And I honestly think that would be worse, even if lambda didn't have a<br>
> code smell.  It focuses attention on the fact that you're creating a<br>
> callable, instead of on the fact that you're grabbing the name<br>
> attribute.</p>
<p>I disagree here. I find the fact that a lambda function shows me the expression I would normally use to get the quantity I'm interested in makes it easier for me to read. When I look at it I don't see it as a callable function but as an expression that I'm passing for use somewhere else.</p>

<p>><br>
> > In general it is bad to conflate scalar/sequence semantics so that a caller<br>
> > should get a different type of object depending on the length of a<br>
> > sequence.<br>
><br>
> Yeah, but that can't really be solved well in python, except maybe by<br>
> never extending an API to handle sequences.  I would personally not<br>
> consider that an improvement.<br>
><br>
> Part of the problem is that the cleanest way to take a variable number<br>
> of arguments is to turn them into a sequence under the covers (*args),<br>
> even if they weren't passed that way.<br>
><br>
> -jJ</p>
<p>You can extend an API to support sequences by adding a new entry point. This is a common idiom in python: think list.append vs list.extend.</p>
<p>Oscar <br>
</p>