Подтвердить что ты не робот

Сортировка списка кортежей по второму значению, reverse = True, а затем по ключу, reverse = False

Мне нужно сначала отсортировать словарь, значения с reverse=True и повторить значения, сортировать по ключам, reverse=False

До сих пор у меня этот

dict = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(dict.items(), key=lambda x: (x[1],x[1]), reverse=True)

который возвращает...

[('B', 3), ('A', 2), ('J', 1), ('I', 1), ('A', 1)]

но мне это нужно:

[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

как вы можете видеть, когда значения равны, я могу только сортировать ключ в порядке убывания, как указано... Но как я могу заставить их сортировать все чаще?

4b9b3361

Ответ 1

С вашим входом работает следующее:

d = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]
sorted(d,key=lambda x:(-x[1],x[0]))

Так как ваши "значения" являются числовыми, вы можете легко изменить порядок сортировки, изменив знак.

Другими словами, этот сортировка упорядочивает по значению (-x[1]) (отрицательный знак сначала ставит большие числа), а затем для чисел, которые являются одинаковыми, он заказывает в соответствии с ключом (x[0]).

Если ваши значения не могут быть легко "сведены на нет", чтобы сначала поставить большие предметы, легко разобраться в следующем:

from operator import itemgetter
d.sort(key=itemgetter(0))
d.sort(key=itemgetter(1),reverse=True)

который работает, потому что сортировка python устойчива.

Ответ 2

In [4]: l = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

In [5]: sorted(l, key=lambda (x,y):(-y,x))
Out[5]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

Ответ 3

вы можете использовать collections.defaultdict:

In [48]: from collections import defaultdict

In [49]: dic=[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]

In [50]: d=defaultdict(list)

In [51]: for x,y in dic:
    d[y].append(x)
    d[y].sort()          #sort the list

теперь d выглядит примерно так:

 defaultdict(<type 'list'>, {1: ['A', 'I', 'J'], 2: ['A'], 3: ['B']}

то есть. Новый dict с 1,2,3... как клавиши и соответствующие алфавиты, сохраненные в списках как значения.

Теперь вы можете выполнить итерацию по sorted(d.items) и получить желаемый результат с помощью itertools.chain() и itertools.product().

In [65]: l=[ product(y,[x]) for x,y in sorted(d.items(),reverse=True)]

In [66]: list(chain(*l))
Out[66]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]