Sort dict in jinja2 loop


Question

I'm still learning jinja2 and flask and I'm having a difficulty using dictsort in jinja2.

So I'm passing this dict into a jinja2 template:

{'PEDD United': {'id': 37828, 'rank': 12, 'totalpts': 307},'Fc Mbonabushia': {'id': 205633, 'rank': 6, 'totalpts': 356},'FC Slurp': {'id': 933573, 'rank': 11, 'totalpts': 312},'KFC_Overijse': {'id': 38861, 'rank': 5, 'totalpts': 362},'Fc Paris': {'id': 1538051, 'rank': 2, 'totalpts': 396}}

What I want is create a table that is sorted by the value of the key 'totalpts'. I tried all sort of things and it just doesn't take totalpts into account when "sorting".

Here's one of my code:

        <table class="table table-bordered">
        {% for team in league %}
            <tr>
                <td>{{team}}</td>
                {% for data in league[team]|dictsort(league[team]['totalpts']) %}
                <td>{{ league[team]['totalpts'] }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>

by it doesn't sort anything in this case... Just print the value in the table without any order...

Anyone can help me out?

thanks

1
17
10/7/2012 9:16:15 AM

Accepted Answer

The way you're doing this will not work, because as soon as you use {% for team in league %}, you're already using the unsorted dict and extracting the key,value pair from it.

I think |dictsort may not be able to help you in this case because you cannot sort by either key or value, but by the value's (sub-dict's) value for 'totalpts'.

Instead, you should sort this dictionary before passing it to the template, in the following way:

>>> from collections import OrderedDict
>>> league={'PEDD United': {'id': 37828, 'rank': 12, 'totalpts': 307},'Fc Mbonabushia': {'id': 205633, 'rank': 6, 'totalpts': 356},'FC Slurp': {'id': 933573, 'rank': 11, 'totalpts': 312},'KFC_Overijse': {'id': 38861, 'rank': 5, 'totalpts': 362},'Fc Paris': {'id': 1538051, 'rank': 2, 'totalpts': 396}}
>>> league = OrderedDict(sorted(league.items(), key= lambda x: x[1]['totalpts'], reverse=True))
>>> print league
OrderedDict([('Fc Paris', {'id': 1538051, 'rank': 2, 'totalpts': 396}), ('KFC_Overijse', {'id': 38861, 'rank': 5, 'totalpts': 362}), ('Fc Mbonabushia', {'id': 205633, 'rank': 6, 'totalpts': 356}), ('FC Slurp', {'id': 933573, 'rank': 11, 'totalpts': 312}), ('PEDD United', {'id': 37828, 'rank': 12, 'totalpts': 307})])

To sort the dict, we convert it into a list of tuples of (key ,value) using .items(). Assuming x is one such tuple, x[1] contains the dictionary with the 'totalpts' key.

>>> league.items()[0]
('Fc Paris', {'id': 1538051, 'rank': 2, 'totalpts': 396})  # = x

So now we sort the tuples usingx[1]['totalpts'], using reverse=True for a decreasing order.

A dict itself cannot be sorted, it is an unordered data type - You can either use an OrderedDict, or you can simply use tuples:

>>> sorted(league.items(), key= lambda x: x[1]['totalpts'], reverse=True)
[('Fc Paris', {'id': 1538051, 'rank': 2, 'totalpts': 396}), ('KFC_Overijse', {'id': 38861, 'rank': 5, 'totalpts': 362}), ('Fc Mbonabushia', {'id': 205633, 'rank': 6, 'totalpts': 356}), ('FC Slurp', {'id': 933573, 'rank': 11, 'totalpts': 312}), ('PEDD United', {'id': 37828, 'rank': 12, 'totalpts': 307})]
17
10/7/2012 12:22:07 PM

You could sort it to an ordered list using sorted:

league = sorted(league, key= lambda x: -league[x]['totalpts'])

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon