По сути, вы ищете itemgetter
с range
:
from operator import itemgetter
standings = ... # your dictionary of dictionaries
n = 5 # number of keys to sort on (1, 2, 3, ..., n)
# The following will collect values by 'points', 1, 2, ..., n in a tuple:
get_values = itemgetter('points', *range(1, n + 1))
result = sorted(standings,
key=lambda x: get_values(standings[x]),
reverse=True)
# [2, 1, 3]
Объяснение:
Чтобы выполнить сортировку по нескольким ключам, вы можете использовать itemgetter
, чтобы создать функцию, которая будет возвращать кортеж значений по указанным ключам.Итак, в качестве простого примера, если у вас будет этот словарь:
my_dict = {1: 10, 2: 20, 3: 30, 4: 40, 5: 50, 'player': 'Ben'}
, и вы захотите получить значения по ключам player
, 1
и 2
, вы должны написать:
from operator import itemgetter
get_values = itemgetter('player', 1, 2)
get_values(my_dict)
# ('Ben', 10, 20)
Теперь, поскольку количество значений может варьироваться и это фактически упорядоченные целые числа (1, 2, 3, ...), вы можете распаковать заданное range
в itemgetter
:
get_values = itemgetter('player', *range(1, 4)) # 'player', 1, 2, 3
get_values(my_dict)
# ('Ben', 10, 20, 30)
Наконец, для вашего данного примера словаря словарей мы получаем эти кортежи для каждого дочернего словаря и сортируем по ним:
standings = {1: {1: 1, 2: 0, 3: 1, 4: 0, 5: 0, 'player': 'Jack', 'points': 15},
2: {1: 1, 2: 0, 3: 2, 4: 2, 5: 0, 'player': 'Kate', 'points': 15},
3: {1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 'player': 'Sawyer', 'points': 5}}
max_key = 5 # you may also calculate it as a max integer key
get_values = itemgetter('points', *range(1, n + 1))
result = sorted(standings, key=lambda x: get_values(standings[x]))
# [3, 1, 2]
# or reversed:
sorted(standings,
key=lambda x: get_keys(standings[x]),
reverse=True)
# [2, 1, 3]