473,394 Members | 1,700 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Sorting a list of objects by multiple attributes

Hi,

I am trying to come up with a clean and simple way to sort a list of
objects (in this case SQLObject instances) by multiple attributes.

e.g. a Person object may have an age, a lastName, and a firstName.

I'd like to be able to arbitrarily sort by any combination of those in
any order.

I would especially like it to be clear and simple, since I am
converting a web app from using SQL to using an ORM only and so the
sorting will actually be controlled by variables coming from SELECTs in
a web form. In SQL this is easy enough to accomplish, and I can do it
in python with L.sort(key=lambda i: i.whatever). But for the multiple
attribute case, I'm at a bit of a loss.

Thanks for any help.

-Steve

Apr 11 '06 #1
12 17733
gry
For multiple keys the form is quite analogous:

L.sort(key=lambda i: (i.whatever, i.someother, i.anotherkey))

I.e., just return a tuple with the keys in order from your lambda.
Such tuples sort nicely.

-- George Young

Apr 11 '06 #2
If you are lambda-phobic (as I am) this should also work for an
arbitrary set of attributes:

attrs = 'attr1 attr2 attr3'.split()
sortlist = [[getattr(o,a) for a in attrs] + [o] for o in objects]
sorted_objects = [x[-1] for x in sorted(sortlist)]

-Noah

Apr 11 '06 #3
gr*@ll.mit.edu wrote:
For multiple keys the form is quite analogous:

L.sort(key=lambda i: (i.whatever, i.someother, i.anotherkey))

I.e., just return a tuple with the keys in order from your lambda.
Such tuples sort nicely.


In Python 2.5 you can do this with operator.attrgetter():

L.sort(key=operator.attrgetter('whatever', 'someother', 'anotherkey'))

Kent
Apr 11 '06 #4
Kent Johnson wrote:
In Python 2.5 you can do this with operator.attrgetter():
L.sort(key=operator.attrgetter('whatever', 'someother', 'anotherkey'))


Note: this is also available in Python 2.4

--Scott David Daniels
sc***********@acm.org
Apr 11 '06 #5
Scott David Daniels wrote:
Kent Johnson wrote:
In Python 2.5 you can do this with operator.attrgetter():
L.sort(key=operator.attrgetter('whatever', 'someother', 'anotherkey'))


Note: this is also available in Python 2.4


No, the ability to specify more than one attribute name, making a getter
that returns a tuple, is a Python 2.5 enhancement. In 2.4:

In [1]: import operator

In [2]: operator.attrgetter('whatever', 'someother', 'anotherkey')
------------------------------------------------------------
Traceback (most recent call last):
File "<ipython console>", line 1, in ?
TypeError: attrgetter expected 1 arguments, got 3

Kent
Apr 11 '06 #6
[George Young]
For multiple keys the form is quite analogous:

L.sort(key=lambda i: (i.whatever, i.someother, i.anotherkey))

[Noah] If you are lambda-phobic (as I am) this should also work for an
arbitrary set of attributes:

attrs = 'attr1 attr2 attr3'.split()
sortlist = [[getattr(o,a) for a in attrs] + [o] for o in objects]
sorted_objects = [x[-1] for x in sorted(sortlist)]


The cult of lambda avoidance has lost contact with reality. Some
Pythonistas now habitually twist their code into knots rather than use
lambda. The above code fragment is a case in point -- it is shocking
that the poster deems the three-line rewrite as an improvement on
George's clear and succinct code fragment.

Lambda avoidance is rooted in two things, an aversion to the keyword
name and an observation that misuse can result in atrocious code. Also,
some of the use cases have fallen by the wayside with the introduction
of listcomps, genexps, and operator.attrgetter. Still, some use cases
remain and there is no reason to mangle your code in the name of a
foolish psuedo-principle.

My advice: use lambda when appropriate and don't feel guilty about it

Apr 11 '06 #7
Kent Johnson wrote:
Scott David Daniels wrote:
Kent Johnson wrote:
In Python 2.5 you can do this with operator.attrgetter():
L.sort(key=operator.attrgetter('whatever', 'someother', 'anotherkey'))


Note: this is also available in Python 2.4


No, the ability to specify more than one attribute name, making a getter
that returns a tuple, is a Python 2.5 enhancement.


Yup, sorry about that. When I installed 2.5a1 the shortcuts I used for
2.4 got switched w/o my noticing (I did try it first). I have now made
my 2.4 shortcuts more explicit (so the next time I'll do this stupid
thing is likely on 2.6).

--
-Scott David Daniels
sc***********@acm.org
Apr 11 '06 #8
I'm sure my avoidance of lambdas as due as much to laziness as
adherence to principle. This is a good opportunity to learn about them.
I suggested the above because it wasn't obvious to me how one would
pass the arbitrary set of attributes to the lambda expression (and I
envisioned them being specified as strings in this case, since the set
of attributes will be coming from a web form).

So what about the following (attrgetter aside)?

attrs = 'attr1 attr2 attr3'.split()
L.sort(key=lambda i: [getattr(i,a) for a in attrs])

-Noah

Apr 12 '06 #9
Raymond Hettinger wrote:

The cult of lambda avoidance has lost contact with reality. [...]
Lambda avoidance is rooted in two things, an aversion to the keyword
name [...]


Let's push the diagnosis a bit further : the aversion to the keyword
"lambda" has to do with the fact that it ignores the english word used
by all non-geeks to convey the meaning, eg "given"
Apr 12 '06 #10
Azolex:
Let's push the diagnosis a bit further : the aversion to the keyword
"lambda" has to do with the fact that it ignores the english word used
by all non-geeks to convey the meaning, eg "given"


Right. However, Guido has said that lambda is here to stay,
so it's time to get over it.
Raymond

Apr 12 '06 #11
[Noah]
I suggested the above because it wasn't obvious to me how one would
pass the arbitrary set of attributes to the lambda expression (and I
envisioned them being specified as strings in this case, since the set
of attributes will be coming from a web form).

So what about the following (attrgetter aside)?

attrs = 'attr1 attr2 attr3'.split()
L.sort(key=lambda i: [getattr(i,a) for a in attrs])


When starting with attribute names in a list of strings,
this code looks fine. The Py2.5 version of attrgetter
will be even cleaner:

L.sort(key=attrgetter(*attrs))

Apr 12 '06 #12
Raymond Hettinger wrote:
Azolex:
Let's push the diagnosis a bit further : the aversion to the keyword
"lambda" has to do with the fact that it ignores the english word used
by all non-geeks to convey the meaning, eg "given"


Right. However, Guido has said that lambda is here to stay,
so it's time to get over it.


You are saying lambda is a given ? ;)

I've not observed the BDFL's pronouncement, so I have to ask : was it
clear from his words that he meant the actual keyword, or could it be he
just meant the construct while refering to it by the keyword ?
Apr 12 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: dasod | last post by:
I would like to know if my method to remove list objects is correct in this small test program. It seems to me that there might be a simplier way, but I'm afraid I don't know enough about list...
5
by: Felix Collins | last post by:
Hi All, does anyone know any cleaver tricks to sort a list of outline numbers. An outline number is a number of the form... 1.2.3 they should be sorted in the following way... 1 1.1 1.2
0
by: gabe_pu | last post by:
List Box Multiple Selections I have a list box on my page and I´m trying to add new items on it. The insert operation must be under the selected item. When I make the insertion it is done ...
4
by: R | last post by:
Hi All, I have problem with sorting nodes I want sort them by columns c1, c2 also I have node <root><sort ActiveField="c0"/></root> ActiveField attribute is set by user. I'm sorting 'row'...
2
by: Daz | last post by:
Hi everyone. I am trying to make a program which handles about 70 different objects, of the same type. The properties are as follows: std::string ItemName int ItemType int Calories int...
3
by: bkamrani | last post by:
Hello, Sorry guys for this newbie questions. But I wonder if there is a standard or build-in method to know the methods of a class? I'm not originally a progrommer and I have worked with...
7
by: Andy | last post by:
Hi, I'm trying to search and print any no# of Python keywords present in a text file (say - foo.txt), and getting the above error. Sad for not being able to decipher such a simple problem (I can...
3
by: TechieGrl | last post by:
Hello. It's been awhile since I've been in the XML world, but before I go down a possibly unnecessary path, I wanted to ask about using CSS and XML files. Is it possible to style multiple...
2
by: ihimitsu | last post by:
Hi friends guide me to sorting java list contains multiple list objects
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.