Сортировка списка с двумя условиями - PullRequest
0 голосов
/ 18 июня 2019

У меня есть список строк, которые я хотел бы отсортировать. Однако некоторые строки - это одно слово, другие - два слова. Кроме того, я хотел бы сначала отсортировать по второму слову, а затем по первому.

Я относительно новичок в идее лямбда-функций, а также в том, как работает ключ для метода sort (), поэтому я попробовал следующее (что не работает):

list_to_sort = ['1 month', '1 year', '3 months', '3 years', '6 months', 'daily']

def sort_func(x):
    x.split()
    if len(x) == 1:
        return x[0]
    else:
        return x[1]

cols.sort(key=sort_func)

# I would like the output to be: 
# ['daily', '1 month', '3 months', '6 months', '1 year', '3 years']

Вместо этого список не меняется вообще. Я не слишком уверен, как работает "key =" в методе sort ().

Ответы [ 3 ]

2 голосов
/ 18 июня 2019

Вы были почти там, x.split() возвращает новый список, поэтому вам нужно будет присвоить возвращаемое значение переменной. Кроме того, поскольку одно из ваших слов после разбиения - это число с плавающей точкой, вам необходимо позаботиться об этом при создании ключа

list_to_sort = ['', '1 month', '1 year', '3 months', '3 years', '6 months', 'daily', '11 months', '12 years']

def sort_func(x):

    #Assign result of split to li
    li = x.split()

    #If 1 element, return word, 0
    if len(li) == 1:
        return li[-1], 0
    #If 2 elements, return word and number cast to int
    elif len(li) == 2:
        return li[-1], int(li[0])

    #If no elements, return empty string and 0
    else:
        return '',0

list_to_sort.sort(key=sort_func)
print(list_to_sort)

Выход будет

['', 'daily', '1 month', '3 months', '6 months', '11 months', '1 year', '3 years', '12 years']
1 голос
/ 18 июня 2019

Вот еще одно решение:

list_to_sort = ['1 month', '1 year', '3 months', '3 years', '6 months', 'daily']

list_to_sort = sorted(list_to_sort, key=lambda x: tuple(reversed(x.split())))
print(list_to_sort)

# >> ['daily', '1 month', '3 months', '6 months', '1 year', '3 years']

NB : Это должно работать независимо от количества слов, включая пустые строки.

Пример:

['', 'daily', '2 months 1 day', '3 months', '6 months', '1 year', '3 years']

Обновление : имейте в виду, что числа в ваших строках будут отсортированы как символы, а не как целые числа:

['1', '11', '2', ...]

Если вы хотите избежать этого, строку выше следует изменить на:

list_to_sort = sorted(list_to_sort, key=lambda x: tuple(reversed([float(item) if item.isnumeric() else item for item in x.split()])))
1 голос
/ 18 июня 2019

.split не на месте. x.split() создает список и выбрасывает его.

Поскольку вы по сути сортируете по последнему слову (если у вас есть 1 слово, тогда «последнее слово» - это 1 слово), лучшей реализацией для sort_func будет

return x.split()[-1]

или как лямбда:

cols.sort(key=lambda x: x.split()[-1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...