Re: [Tutor] sorting objects in lists by 2 attr
Philippe Niquille wrote: Tanks a mill! I don't know why I searched so far.. Anyway, I wrapped the django custom SQL call and built a nice dictionary out of the resulting rows (which is similar to querysets). See http://www.djangosnippets.org/snippets/207/ http://www.djangosnippets.org/snippets/207/ for details. That code could be much simpler. You wrote, fdicts = [] for row in rows: i = 0 cur_row = {} for key in qkeys: cur_row[key] = row[i] i = i+1 fdicts.append(cur_row) So qkeys is a list of names for the values in each row. You can convert the list of names and row into a dict with cur_row = dict(zip(qkeys, row)) zip(qkeys, row) converts the two list into a list of key, value pairs which can be used directly to create the dict. This is simple enough to use in a list comprehension, so the outer loop can be written as fdicts = [ dict(zip(qkeys, row)) for row in rows ] To answer your original question, the best way to sort on multiple attributes is to make a key function that returns a tuple of the desired attributes and provide that to sort. In Python 2.5, the function operator.attrgetter() will create the key function for you, so you can write import operator newscore.sort(key=operator.attrgetter('score', 'owner')) or whatever the correct attributes are. In older Python attrgetter only takes a single argument so you have to create the key function yourself: def key_func(item): return (item.score, item.owner) newscore.sort(key=key_func) Kent ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] sorting objects in lists by 2 attr
Hi I have a hard time sorting an object list. Perhaps this is kind of a noob question, but I would very much appreciate any help! Using django I get a QuerySet of Score objects which are sorted by the actual score, the actual score divided by the max. possible score (so sorting by two db fields). I then need to loop through that queryset and sum up all the score objects which belong to the same user into one Score objects. This works (see code below). The problem I now have, is that I lost the sorting order, as described above. How would I resort it with a python algortithm instead of SQL? scores = Score.objects.order_by('score', 'score2','owner') # filter by course, MC !! # loop through scores to regroup by user newscore = [] for s in scores: i = False # loop through new object container and check for existant user index, add scores if existant for ns in newscore: if s.owner == ns.owner: ns.score = int(ns.score) + int(s.score) ns.maxscore = int(ns.maxscore) + int(s.maxscore) i = True # otherwise append new user index object, work with it later, perhaps (if more user objects exist) if i == False: newscore.append(s) - I did fiddle around with .sort() but didn't get any useful results (and it would only sort by one object..). class CmpAttr: def __init__(self, attr): self.attr = attr def __call__(self, x, y): return cmp(getattr(x, self.attr), getattr(y, self.attr)) newscore.sort(CmpAttr(score)) ps. could it be, that this maillist is blocking some e-mail addresses? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects in lists by 2 attr
Philippe Niquille wrote: Hi I have a hard time sorting an object list. Perhaps this is kind of a noob question, but I would very much appreciate any help! Using django I get a QuerySet of Score objects which are sorted by the actual score, the actual score divided by the max. possible score (so sorting by two db fields). I then need to loop through that queryset and sum up all the score objects which belong to the same user into one Score objects. This works (see code below). The problem I now have, is that I lost the sorting order, as described above. How would I resort it with a python algortithm instead of SQL? This is not the question you're asking, but my first though was, why not have SQL do the summing for you using sum() and group by? scores = Score.objects.order_by('score', 'score2','owner') # filter by course, MC !! # loop through scores to regroup by user newscore = [] for s in scores: i = False # loop through new object container and check for existant user index, add scores if existant for ns in newscore: if s.owner == ns.owner: ns.score = int(ns.score) + int(s.score) ns.maxscore = int(ns.maxscore) + int(s.maxscore) i = True # otherwise append new user index object, work with it later, perhaps (if more user objects exist) if i == False: newscore.append(s) - I did fiddle around with .sort() but didn't get any useful results (and it would only sort by one object..). class CmpAttr: def __init__(self, attr): self.attr = attr def __call__(self, x, y): return cmp(getattr(x, self.attr), getattr(y, self.attr)) newscore.sort(CmpAttr(score)) ps. could it be, that this maillist is blocking some e-mail addresses? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects in lists by 2 attr
Philippe Niquille [EMAIL PROTECTED] wrote The problem I now have, is that I lost the sorting order, as described above. How would I resort it with a python algortithm instead of SQL? Why not use SQL? Best to get the highest quality data into your program that you can, the earlier you clean it the better. Unless your database is squealing and you need to move load onto your app server then I'd leave the database to handle the data. In fact I might even make it a stored procedure if the database supports those... Alan G. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects in lists by 2 attr
Philippe Niquille wrote: Using django I get a QuerySet of Score objects which are sorted by the actual score, the actual score divided by the max. possible score (so sorting by two db fields). I then need to loop through that queryset and sum up all the score objects which belong to the same user into one Score objects. This works (see code below). I'm with Eric and Alan here; do as much in the DB as possible/practical first, then work with the results in Python. Django's ORM may be able to do your aggregating for you. If not and if your DB has something like PostgreSQL's Views (stored queries) then you can create a database view that filters/sorts/aggregates your data as needed. From there you can create a Django Model associated with the DB View, just like you normally create a Django Model on a DB table. The main difference is that objects returned by the QuerySet on the DB View will be read-only because the DB View is read-only. On the other hand you'll still be able to python-ize your aggregated db data using Django's ORM in a manner you are used to, something like: scores = ModelOnMyDBView.objects.order_by('max_score','owner') I hope that is helpful, Eric. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects in lists by 2 attr
Tanks a mill! I don't know why I searched so far.. Anyway, I wrapped the django custom SQL call and built a nice dictionary out of the resulting rows (which is similar to querysets). See http://www.djangosnippets.org/snippets/207/ for details. Philippe Am 23.07.2007 um 19:28 schrieb Eric Brunson: Philippe Niquille wrote: Hi I have a hard time sorting an object list. Perhaps this is kind of a noob question, but I would very much appreciate any help! Using django I get a QuerySet of Score objects which are sorted by the actual score, the actual score divided by the max. possible score (so sorting by two db fields). I then need to loop through that queryset and sum up all the score objects which belong to the same user into one Score objects. This works (see code below). The problem I now have, is that I lost the sorting order, as described above. How would I resort it with a python algortithm instead of SQL? This is not the question you're asking, but my first though was, why not have SQL do the summing for you using sum() and group by? scores = Score.objects.order_by('score', 'score2','owner') # filter by course, MC !! # loop through scores to regroup by user newscore = [] for s in scores: i = False # loop through new object container and check for existant user index, add scores if existant for ns in newscore: if s.owner == ns.owner: ns.score = int(ns.score) + int(s.score) ns.maxscore = int(ns.maxscore) + int(s.maxscore) i = True # otherwise append new user index object, work with it later, perhaps (if more user objects exist) if i == False: newscore.append(s) - I did fiddle around with .sort() but didn't get any useful results (and it would only sort by one object..). class CmpAttr: def __init__(self, attr): self.attr = attr def __call__(self, x, y): return cmp(getattr(x, self.attr), getattr(y, self.attr)) newscore.sort(CmpAttr(score)) ps. could it be, that this maillist is blocking some e-mail addresses? ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] sorting objects in lists by 2 attr
SQL databases are cool. Make them do as much as they can for you. :-) Philippe Niquille wrote: Tanks a mill! I don't know why I searched so far.. Anyway, I wrapped the django custom SQL call and built a nice dictionary out of the resulting rows (which is similar to querysets). See http://www.djangosnippets.org/snippets/207/ http://www.djangosnippets.org/snippets/207/ for details. Philippe Am 23.07.2007 um 19:28 schrieb Eric Brunson: Philippe Niquille wrote: Hi I have a hard time sorting an object list. Perhaps this is kind of a noob question, but I would very much appreciate any help! Using django I get a QuerySet of Score objects which are sorted by the actual score, the actual score divided by the max. possible score (so sorting by two db fields). I then need to loop through that queryset and sum up all the score objects which belong to the same user into one Score objects. This works (see code below). The problem I now have, is that I lost the sorting order, as described above. How would I resort it with a python algortithm instead of SQL? This is not the question you're asking, but my first though was, why not have SQL do the summing for you using sum() and group by? scores = Score.objects.order_by('score', 'score2','owner') # filter by course, MC !! # loop through scores to regroup by user newscore = [] for s in scores: i = False # loop through new object container and check for existant user index, add scores if existant for ns in newscore: if s.owner == ns.owner: ns.score = int(ns.score) + int(s.score) ns.maxscore = int(ns.maxscore) + int(s.maxscore ) i = True # otherwise append new user index object, work with it later, perhaps (if more user objects exist) if i == False: newscore.append(s) - I did fiddle around with .sort() but didn't get any useful results (and it would only sort by one object..). class CmpAttr: def __init__(self, attr): self.attr = attr def __call__(self, x, y): return cmp(getattr(x, self.attr), getattr(y, self.attr)) newscore.sort(CmpAttr(score)) ps. could it be, that this maillist is blocking some e-mail addresses? ___ Tutor maillist - Tutor@python.org mailto:Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor