Как указать 2 ключа в сортировке (списке) python? - программирование
Подтвердить что ты не робот

Как указать 2 ключа в сортировке (списке) python?

Как отсортировать список строк с помощью key=len сначала, а затем key=str? Я пробовал следующее, но это не давало мне нужного рода:

>>> ls = ['foo','bar','foobar','barbar']
>>> 
>>> for i in sorted(ls):
...     print i
... 
bar
barbar
foo
foobar
>>>
>>> for i in sorted(ls, key=len):
...     print i
... 
foo
bar
foobar
barbar
>>> 
>>> for i in sorted(ls, key=str):
...     print i
... 
bar
barbar
foo
foobar

Мне нужно получить:

bar
foo
barbar
foobar
4b9b3361

Ответ 1

Определите ключевую функцию, которая возвращает кортеж, в котором первый элемент len(str), а второй - сама строка. Затем кортежи сравниваются лексикографически. То есть сначала сравниваются длины; если они равны, то строки сравниваются.

In [1]: ls = ['foo','bar','foobar','barbar']

In [2]: sorted(ls, key=lambda s: (len(s), s))
Out[2]: ['bar', 'foo', 'barbar', 'foobar']

Ответ 2

Ответ от root правильный, но вам не нужна лямбда:

>>> def key_function(x):
        return len(x), str(x)

>>> sorted(['foo','bar','foobar','barbar'], key=key_function)
['bar', 'foo', 'barbar', 'foobar']

В дополнение к альтернативному подходу используется стабильность сортировки, которая позволяет вам сортировать несколько проходов (сначала с помощью вторичного ключа):

>>> ls = ['foo','bar','foobar','barbar']
>>> ls.sort(key=str)                       # secondary key
>>> ls.sort(key=len)                       # primary key

См. Сортировка HOWTO для хорошего руководства по методам сортировки Python.

Ответ 3

Если вы не хотите использовать лямбда:

from operator import itemgetter
ls = ['foo','bar','foobar','barbar']
print sorted([ [x,len(x)] for x in ls ] ,key=itemgetter(1,0))
# print [s[0] for s in sorted([ [x,len(x)] for x in ls ] ,key=itemgetter(1,0))]

Ответ 4

Другая форма, которая работает без лямбда:

>>> [t[1] for t in sorted((len(s),s) for s in ls)]
['bar', 'foo', 'barbar', 'foobar']