Note that there are some explanatory texts on larger screens.

plurals
  1. POSorting a list of dictionaries of objects by dictionary values
    primarykey
    data
    text
    <p>This is related to the various other questions about sorting values of dictionaries that I have read here, but I have not found the answer. I'm a newbie and maybe I just didn't see the answer as it concerns my problem.</p> <p>I have this function, which I'm using as a Django custom filter to sort results from a list of dictionaries. Actually, the main part of this function was answered in a related question on stackoverflow.</p> <pre><code>def multikeysorting(dict_list, sortkeys): from operator import itemgetter def multikeysort(items, columns): comparers = [ ((itemgetter(col[1:]), -1) if col.startswith('-') else (itemgetter(col), 1)) for col in columns] def sign(a, b): if a &lt; b: return -1 elif a &gt; b: return 1 else: return 0 def comparer(left,right): for fn, mult in comparers: result = sign(fn(left), fn(right)) if result: return mult * result else: return 0 return sorted(items, cmp=comparer) keys_list = sortkeys.split(",") return multikeysort(dict_list, keys_list) </code></pre> <p>This filter is called as follows in Django:</p> <pre><code>{% for item in stats|statleaders_has_stat:"TOT_PTS_Misc"|multikeysorting:"-TOT_PTS_Misc.value,TOT_PTS_Misc.player.last_name" %} </code></pre> <p>This means that there are two dictionary values passed to the function to sort the list of dictionaries. The sort works with the dictionary keys, but not the values.</p> <p>How can I sort the and return the dictionary by sorting the list of dictionaries with more than one value? In the example above, first by the value, then by the last_name.</p> <p>Here is an example of the data: <pre> [{u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: DeWitt, Ash Total Points : 6.0>, 'player': &lt; Player: DeWitt, Ash>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Ackerman, Luke Total Points : 18.0>, 'player': &lt; Player: Ackerman, Luke>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Wise, Dan Total Points : 19.0>, 'player': &lt; Player: Wise, Dan>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Allison, Mike Total Points : 18.0>, 'player': &lt; Player: Allison, Mike>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Wolford, Alex Total Points : 18.0>, 'player': &lt; Player: Wolford, Alex>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Okes, Joe Total Points : 18.0>, 'player': &lt; Player: Okes, Joe>}, {u'TOT_PTS_Misc': &lt; StatisticPlayerRollup: Grattan, Paul Total Points : 18.0>, 'player': &lt; Player: Grattan, Paul>}] </pre></p> <p>The listing should be sorted as follows:</p> <pre> LastName Points Wise 19.0 Ackerman 18.0 Allison 18.0 Grattan 18.0 Okes 18.0 Wolford 18.0 Hagg 6.0 DeWitt 6.0 </pre> <p>The TOT_PTS_Misc is an object that contains the player name as well as the number of points. (I hope I am explaining this correct.)</p> <p>But, there should be an arbitrary sort of values, either ascending or descending. Not always that same values and possibly more than two.</p> <hr> <p>So I came up with this solution, but wanted to know if it makes sense and if there is anything that should be changed.</p> <pre> def multikeysorting(dict_list, sortkeys): from operator import itemgetter, attrgetter klist = sortkeys.split(",") vlist = [] for i in klist: vlist.append(tuple(i.split("."))) def getkeyvalue(val_list): result = [] for id,val in enumerate(val_list): if val[0].startswith('-'): if len(val) == 2: result.append((itemgetter(val[0][1:]).attrgetter(val[1]), -1)) else: att = val[1] for j in val[2:]: att = att + "." + j result.append((itemgetter(val[0][1:]).attrgetter(att), -1)) else: if len(val) == 2: result.append((itemgetter(val[0]).attrgetter(val[1]), 1)) else: att = val[1] for j in val[2:]: att = att + "." + j result.append((itemgetter(val[0]).attrgetter(att), 1)) return result return sorted(dict_list, key=getkeyvalue(vlist)) </pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload