Allow key='attribute_name' to various sorting functions
I often want to sort objects by an attribute. It's cumbersome to do this: sorted(entries, key=lambda entry: entry.datetime_created) Why not allow this instead: sorted(entries, key='datetime_created') The `sorted` function can check whether the `key` argument is a string, and if so do an attribute lookup. Since I see no other possible use of a string input to `key`, I don't see how this feature would harm anyone. What do you think? Thanks, Ram.
On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created')) You can alias attrgetter to an even shorter name if you like. Explicit utility functions are better than implicit special-case behaviors. Why should a string be special-cased to attribute lookup rather than, say, __getitem__ lookup? Carl
On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
I often want to sort objects by an attribute. It's cumbersome to do
On 04/11/2013 04:24 PM, Ram Rachum wrote: this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
Explicit utility functions are better than implicit special-case behaviors. Why should a string be special-cased to attribute lookup
rather than, say, __getitem__ lookup?
Right, these are options too. I'd guess that attribute lookup is more common, but maybe I'm wrong.
Carl _______________________________________________ Python-ideas mailing list Python...@python.org javascript: http://mail.python.org/mailman/listinfo/python-ideas
On Apr 11, 2013, at 6:52 PM, Ram Rachum
On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote: On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
Explicit utility functions are better than implicit special-case behaviors. Why should a string be special-cased to attribute lookup rather than, say, __getitem__ lookup?
Right, these are options too. I'd guess that attribute lookup is more common, but maybe I'm wrong.
Carl _______________________________________________ Python-ideas mailing list Python...@python.org http://mail.python.org/mailman/listinfo/python-ideas _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
Special cases aren't special enough to break the rules. ----------------- Donald Stufft PGP: 0x6E3CBCE93372DCFA // 7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA
Donald Stufft writes:
Special cases aren't special enough to break the rules.
Not to mention: In the face of ambiguity, refuse to guess. N.B. This is part of why Steven d'A changes from -1 to +0 on "key=3". This looks like POSIX sort(1), and cut(1), a bit, doesn't it.
On 11 April 2013 23:52, Ram Rachum
On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up. Oscar
A more generic and useful thing would be kind of what scala/groovy have:
shorthands for defining function literals:
Groovy:
myList.sort{it.startTime}
Scala:
myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime"
or python's "lambda x: x.startTime". You could probably get something
similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a
lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin
On 11 April 2013 23:52, Ram Rachum
wrote: On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
Interesting!
On Fri, Apr 12, 2013 at 2:33 AM, Haoyi Li
A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin < oscar.j.benjamin@gmail.com> wrote:
On 11 April 2013 23:52, Ram Rachum
wrote: On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
You can have something like that with this module I created:
https://github.com/jbvsmo/funcbuilder
from funcbuilder import f
sorted(entries, key=f.datetime_created)
Some features in this module are *very* experimental, but are also very
cool...
João Bernardo
2013/4/11 Ram Rachum
Interesting!
On Fri, Apr 12, 2013 at 2:33 AM, Haoyi Li
wrote: A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin < oscar.j.benjamin@gmail.com> wrote:
On 11 April 2013 23:52, Ram Rachum
wrote: On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
On 04/11/2013 04:24 PM, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
Awesome module!
On Fri, Apr 12, 2013 at 2:58 AM, João Bernardo
You can have something like that with this module I created: https://github.com/jbvsmo/funcbuilder
from funcbuilder import f sorted(entries, key=f.datetime_created)
Some features in this module are *very* experimental, but are also very cool...
João Bernardo
2013/4/11 Ram Rachum
Interesting!
On Fri, Apr 12, 2013 at 2:33 AM, Haoyi Li
wrote: A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin < oscar.j.benjamin@gmail.com> wrote:
On 11 April 2013 23:52, Ram Rachum
wrote: On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote:
On 04/11/2013 04:24 PM, Ram Rachum wrote: > I often want to sort objects by an attribute. It's cumbersome to do > this: > > sorted(entries, key=lambda entry: entry.datetime_created) > > Why not allow this instead: > > sorted(entries, key='datetime_created')
from operator import attrgetter sorted(entries, key=attrgetter('datetime_created'))
You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
It was something I did for fun, so I never had the time to add proper
documentation.
You can see the best examples to use by reading the doctests from __init__ .
BTW, It abuses a lot of Python 3 constructions, so you can't use Python 2.x
João Bernardo
2013/4/11 Ram Rachum
Awesome module!
On Fri, Apr 12, 2013 at 2:58 AM, João Bernardo
wrote: You can have something like that with this module I created: https://github.com/jbvsmo/funcbuilder
from funcbuilder import f sorted(entries, key=f.datetime_created)
Some features in this module are *very* experimental, but are also very cool...
João Bernardo
2013/4/11 Ram Rachum
Interesting!
On Fri, Apr 12, 2013 at 2:33 AM, Haoyi Li
wrote: A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin < oscar.j.benjamin@gmail.com> wrote:
On 11 April 2013 23:52, Ram Rachum
wrote: On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote: > > On 04/11/2013 04:24 PM, Ram Rachum wrote: > > I often want to sort objects by an attribute. It's cumbersome to do > > this: > > > > sorted(entries, key=lambda entry: entry.datetime_created) > > > > Why not allow this instead: > > > > sorted(entries, key='datetime_created') > > from operator import attrgetter > sorted(entries, key=attrgetter('datetime_created')) > > You can alias attrgetter to an even shorter name if you like.
That's still cumbersome in my opinion.
I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
Very crafty! I liked the idea of funcbuilder f as replacement for lambdas
and the result is true pythonic!
2013/4/11 João Bernardo
It was something I did for fun, so I never had the time to add proper documentation. You can see the best examples to use by reading the doctests from __init__.
BTW, It abuses a lot of Python 3 constructions, so you can't use Python 2.x
João Bernardo
2013/4/11 Ram Rachum
Awesome module!
On Fri, Apr 12, 2013 at 2:58 AM, João Bernardo
wrote: You can have something like that with this module I created: https://github.com/jbvsmo/funcbuilder
from funcbuilder import f sorted(entries, key=f.datetime_created)
Some features in this module are *very* experimental, but are also very cool...
João Bernardo
2013/4/11 Ram Rachum
Interesting!
On Fri, Apr 12, 2013 at 2:33 AM, Haoyi Li
wrote: A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
-Haoyi
On Thu, Apr 11, 2013 at 7:05 PM, Oscar Benjamin < oscar.j.benjamin@gmail.com> wrote:
On 11 April 2013 23:52, Ram Rachum
wrote: > On Friday, April 12, 2013 1:35:20 AM UTC+3, Carl Meyer wrote: >> >> On 04/11/2013 04:24 PM, Ram Rachum wrote: >> > I often want to sort objects by an attribute. It's cumbersome to do >> > this: >> > >> > sorted(entries, key=lambda entry: entry.datetime_created) >> > >> > Why not allow this instead: >> > >> > sorted(entries, key='datetime_created') >> >> from operator import attrgetter >> sorted(entries, key=attrgetter('datetime_created')) >> >> You can alias attrgetter to an even shorter name if you like. > > That's still cumbersome in my opinion. I don't think it's that cumbersome. Leaving aside the import line you're only having to specify two things for your key function: that it's an attribute (attrgetter) and the name of the attribute ('datetime_created'). It's not possible for this to be any more succinct without using special case implicit rules which are generally a bad thing. I like the fact that the API for the sorted function is so simple I can remember all of its arguments and exactly what they do without ever needing to look it up.
Oscar _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Carlo Pires
On 12 April 2013 00:33, Haoyi Li
A more generic and useful thing would be kind of what scala/groovy have: shorthands for defining function literals:
Groovy: myList.sort{it.startTime}
Scala: myList.sort(_.startTime)
Where "_.startTime" and "it.startTime" are shorthand for "x => x.startTime" or python's "lambda x: x.startTime". You could probably get something similar in python:
sorted(entries, key = x.datetime_created)
if you did some magic with x to make looking up an attribute return a lambda that returns that attribute of its argument.
You can do that if you want to: import operator class X(object): def __getattribute__(self, attrname): return operator.attrgetter(attrname) def __getitem__(self, index): return operator.itemgetter(index) x = X() Oscar
On 12/04/13 08:24, Ram Rachum wrote:
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
The `sorted` function can check whether the `key` argument is a string, and if so do an attribute lookup.
Why an attribute lookup? Why not a key lookup? Using a trivial lambda makes it obvious what you want: key=lambda obj: obj.name key=lambda obj: obj[name] and is more convenient (although probably slower) than the alternatives: key=operator.attrgetter(name) key=operator.itemgetter(name) without ambiguity or guessing what the caller intended. It also avoids masking TypeError errors if you call with a non-literal argument that happens to be a string. If we allow sorted etc. to guess what the caller wants with strings, should it also guess what they want with integers? key=3 equivalent to key=lambda obj: obj[3] Hmmm... tempting... that would make sorting tuples by a specific field really easy, which is an extremely common use case, and unlike strings, there's no ambiguity. So... -1 on allowing key='string' shortcuts, +0 on allowing key=3 shortcuts. -- Steven
Le Fri, 12 Apr 2013 09:48:57 +1000,
Steven D'Aprano
If we allow sorted etc. to guess what the caller wants with strings, should it also guess what they want with integers?
key=3 equivalent to key=lambda obj: obj[3]
Hmmm... tempting... that would make sorting tuples by a specific field really easy, which is an extremely common use case, and unlike strings, there's no ambiguity.
So... -1 on allowing key='string' shortcuts, +0 on allowing key=3 shortcuts.
-1 on both :-) Regards Antoine.
Ram Rachum
I often want to sort objects by an attribute. It's cumbersome to do this:
sorted(entries, key=lambda entry: entry.datetime_created)
Why not allow this instead:
sorted(entries, key='datetime_created')
The `sorted` function can check whether the `key` argument is a string, and if so do an attribute lookup.
Since I see no other possible use of a string input to `key`, I don't see how this feature would harm anyone.
What do you think?
Thanks, Ram.
------------------------------------------------------------------------
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
I think it's a very bad idea to try to overload the key argument, imo a separate kwarg of sorted would be fine though. E.g: sorted(iterable, attribute='someattr') -- Markus (from phone)
participants (12)
-
Antoine Pitrou
-
Carl Meyer
-
Carlo Pires
-
Donald Stufft
-
Haoyi Li
-
João Bernardo
-
Markus Unterwaditzer
-
Oscar Benjamin
-
Ram Rachum
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Yuval Greenfield