Home > Net >  sorting a nested dictionary by 3 criteria
sorting a nested dictionary by 3 criteria

Time:08-09

I have a nested dictionary and I want to sort it by 3 fields, firstly by points secondly by wins(if points are equal) and lastly by alphabet if both points and wins are equal.

My dictionary:

{'Iran': {'draws': 1,
          'goal difference': 0,
          'loses': 1,
          'points': 4,
          'wins': 1},
 'Morocco': {'draws': 1,
             'goal difference': 0,
             'loses': 1,
             'points': 4,
             'wins': 1},
 'Portugal': {'draws': 1,
              'goal difference': 0,
              'loses': 1,
              'points': 4,
              'wins': 1},
 'Spain': {'draws': 1,
           'goal difference': 0,
           'loses': 1,
           'points': 4,
           'wins': 1}}

My code:

sort_data=sorted(dic.keys(),key=lambda x:(-dic[x]["points"],dic[x]["wins"]))
for items in sort_data:
    x=dic[items]
    print(items," ",str(x).replace("'", "").replace("{","").replace("}", ""))

my code dose not work in this case and dose not sort it by alphabet when all the situations are equal.Could you help me?

CodePudding user response:

I suggest using dic.items() rather than dic.keys(), although that's mostly a matter of taste.

def sorted_dict(dic):
    def key(x):
        k,v = x
        return (v['points'], v['wins'], k)
    return dict(sorted(dic.items(), key=key))

dic1 = {'Iran': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1}, 'Morocco': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1}, 'Portugal': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1}, 'Spain': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1}}

dic2 = sorted_dict(dic1)

print(dic2)
# {'Iran': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1},
#  'Morocco': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1},
#  'Portugal': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1},
#  'Spain': {'draws': 1, 'goal difference': 0, 'loses': 1, 'points': 4, 'wins': 1}}

Note that in your dictionary, all countries have the same number of points and wins, and the countries are already sorted in alphabetical order, so this is a terrible example to test whether the sort worked correctly or not.

CodePudding user response:

You could use dict.items with a lambda instead:

import json  # For pretty printing only.

table = {
    'Iran': {
        'draws': 1,
        'goal difference': 0,
        'loses': 1,
        'points': 4,
        'wins': 1
    },
    'Morocco': {
        'draws': 1,
        'goal difference': 0,
        'loses': 1,
        'points': 4,
        'wins': 1
    },
    'Portugal': {
        'draws': 1,
        'goal difference': 0,
        'loses': 1,
        'points': 4,
        'wins': 1
    },
    'Spain': {
        'draws': 1,
        'goal difference': 0,
        'loses': 1,
        'points': 4,
        'wins': 1
    }
}

sorted_table = dict(
    sorted(table.items(),
           key=lambda kvp: (-kvp[1]['points'], -kvp[1]['wins'], kvp[0])))
print(json.dumps(sorted_table, indent=4))

Output:

{
    "Iran": {
        "draws": 1,
        "goal difference": 0,
        "loses": 1,
        "points": 4,
        "wins": 1
    },
    "Morocco": {
        "draws": 1,
        "goal difference": 0,
        "loses": 1,
        "points": 4,
        "wins": 1
    },
    "Portugal": {
        "draws": 1,
        "goal difference": 0,
        "loses": 1,
        "points": 4,
        "wins": 1
    },
    "Spain": {
        "draws": 1,
        "goal difference": 0,
        "loses": 1,
        "points": 4,
        "wins": 1
    }
}

Note: No change from input is because input is already sorted...

  • Related