Сортировка на основе 2 атрибутов - PullRequest
0 голосов
/ 13 октября 2018

Я пытаюсь отсортировать числа в лексикографическом (обратном) порядке и от самого короткого до самого длинного числа.Так, например, числа 9989, 989, 9 должны быть переопределены как 9, 9989, 989.

Я пытаюсь этот код:

a.sort(key=lambda x:([x[i] for i in range(len(x))],len(x)), reverse=True)

, но он работает правильно только тогда, когда числа имеютодинаковой длиныКак мне исправить это так, чтобы более короткие числа стояли перед более длинными числами (т. Е. От 9 до 99)?

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Вы вряд ли сможете написать значащую key функцию в Python 3 для этого типа сортировки, не прибегая к функции компаратора и затем используя functools.comp_to_key дляпревратите его в ключевую функцию.

Проверьте, какой из элементов больше, до их минимальной длины (используя zip для итерации на обоих остановках на минимальной длине), если оба одинаковы, проверьте их длину:

from functools import cmp_to_key

def comparator(x, y):
   if x == y: return 0
   for i, j in zip(x, y):
      if i != j:
         return int(j)-int(i) # the reversal is done here
   return 1 if len(x) > len(y) else -1


t = '9989', '989', '9'
print(sorted(t, key=cmp_to_key(comparator)))
# ['9', '9989', '989']

t = '888', '9989', '989', '9', '8'
print(sorted(t, key=cmp_to_key(comparator)))
# ['9', '9989', '989', '8', '888']

Функция сортировки вполне читабельна, не обрабатывается дальше, когда элементы равны, и с zip останавливается на минимальной длине; Адаптивный .

0 голосов
/ 13 октября 2018

Это то, что я придумал, идея похожа на @ решение Эндика , но избегая двойной сортировки и используя int ввод.Требуется импорт math.inf для обработки, например, [9989, 989, 999, 9, 99].

from math import inf
from functools import partial

a = [9989, 989, 9]

def sort_algo(x, k):
    x_str = list(str(x))
    return list(map(int, x_str)) + [inf]*(k-len(x_str))

n = max(map(len, map(str, a)))
sorter = partial(sort_algo, k=n)
a.sort(key=sorter, reverse=True)

print(a)

[9, 9989, 989]
0 голосов
/ 13 октября 2018

Как то так?

a = ['9989', '989', '999', '8', '9'] 
max_a = len(max(a, key=len))  
sorted(a, key=lambda x: x + 'a'*(max_a - len(x)), reverse=True)
# ['9', '999', '9989', '989', '8']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...