Как указать 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
Ответы
Ответ 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']