#python #сортировка #task #dict
Я пытаюсь решать задачи на checkio, и у меня появилась проблема. Задача: Отсортируйте заданный лист так, чтобы его элементы оказались в таком порядке: [4, 6, 2, 2, 6, 4, 4, 4] == [4, 4, 4, 4, 6, 6, 2, 2] ['bob', 'bob', 'carl', 'alex', 'bob'] == ['bob', 'bob', 'bob', 'carl', 'alex'] [17, 99, 42] == [17, 99, 42] Если два элемента появляются одинаковое число раз, они должны записываться в том же порядке, что и в первое появление в изначальном листе. Я использую код: items1 = ["bob", "bob", "carl", "alex", "bob"] items2 = [1, 2, 2, 1] items3 = [4, 6, 2, 2, 6, 4, 4, 4] def frequency_sort(items): result = [] m = dict(pd.value_counts(items)) print('Dictionary from list: ', m) for i in items: if items.count(i) == 1: return items elif items.count(i) == 0: return items else: for item in m: for i1 in range(0, m[item]): result.append(item) return result return items Результат: Input data: ['bob', 'bob', 'carl', 'alex', 'bob'] Dictionary from list: {'bob': 3, 'alex': 1, 'carl': 1} Result: ['bob', 'bob', 'bob', 'alex', 'carl'] **Must be: ['bob', 'bob', 'bob', 'carl', 'alex']** Input data: [1, 2, 2, 1] Dictionary from list: {2: 2, 1: 2} Result: [2, 2, 1, 1] **Must be: [1, 1, 2, 2]** Input data: [4, 6, 2, 2, 6, 4, 4, 4] Dictionary from list: {4: 4, 6: 2, 2: 2} Result: [4, 4, 4, 4, 6, 6, 2, 2] Код не работает. Есть 2 ошибки, они выделены. Я не понимаю как словарь при преобразовании сортирует мой лист. Пытался отключить сортировку: m = dict(pd.value_counts(items, sort=False)) Но получилось не очень : Input data: ['bob', 'bob', 'carl', 'alex', 'bob'] Dictionary from list: {'carl': 1, 'bob': 3, 'alex': 1} ['carl', 'bob', 'bob', 'bob', 'alex'] Input data: [1, 2, 2, 1] Dictionary from list: {1: 2, 2: 2} [1, 1, 2, 2] Input data: [4, 6, 2, 2, 6, 4, 4, 4] Dictionary from list: {2: 2, 4: 4, 6: 2} [2, 2, 4, 4, 4, 4, 6, 6] Как решить задачу? Пробовал сделать через листы, но запнулся.
Ответы
Ответ 1
Почему бы не так. Пробегаемся по всем уникальным значениям в порядке появления и заполняем в результат столько, сколько их в исходном листе result = [] for x in [x for i, x in enumerate(items) if i == items.index(x)]: result.extend([x]*items.count(x)) или даже вот так, что по сути тоже самое def frequency_sort(items): result = [] for i, x in enumerate(items): if i == items.index(x): result.extend([x]*items.count(x)) return result Update def frequency_sort(items): temp = [] for i, x in enumerate(items): if i == items.index(x): temp.append([x, [items.count(x), len(items)-i]]) temp = sorted(temp, key = lambda x: x[1], reverse=True) result = [] for x in temp: result.extend([x[0]]*x[1][0]) return resultОтвет 2
Возможно, такой вариант вас устроит: from collections import Counter from itertools import chain def freqlst(lst: list)-> list: return list(chain(*[ [k,]*v for k,v in Counter(lst).items()])) Пррверяем: print(freqlst([4, 6, 2, 2, 6, 4, 4, 4])) # [4, 4, 4, 4, 6, 6, 2, 2] print(freqlst(['bob', 'bob', 'carl', 'alex', 'bob'])) # ['bob', 'bob', 'bob', 'carl', 'alex'] print(freqlst([17, 99, 42])) # [17, 99, 42]Ответ 3
Я решил задачу следующим образом (UPD): def frequency_sort(items: list) -> list: counts = {x:items.count(x) for x in items} sorted_counts = {k: counts[k] for k in sorted(counts.keys(), key=counts.get, reverse=True)} result = [x for x in sorted_counts for _ in range(sorted_counts[x])] return result Примечание: данный код работает, начиная с версии 3.7. counts — это словарь, в котором ключами являются элементы списка items, а значениями — количество вхождений соответствующего ключа в список items. sorted_counts — это словарь counts, отсортированный по значениям ключей в обратном порядке. Словари, начиная с Python 3.7 сохраняют порядок, поэтому отлично подходят под наши цели и удовлетворяют одному из условий задачи. Всё что остаётся — это преобразовать полученный словарь в новый список (result). Этим занимается списковое включение, которое можно переписать следующим образом: result = [] for x in sorted_counts: for _ in range(sorted_counts[x]): result.append(x) Тесты: print(frequency_sort(items1)) # ['bob', 'bob', 'bob', 'carl', 'alex'] print(frequency_sort(items2)) # [1, 1, 2, 2] print(frequency_sort(items3)) # [4, 4, 4, 4, 6, 6, 2, 2] # UPD: Тест из комментария print(frequency_sort(items4)) # [4, 4, 4, 4, 2, 2, 2, 6, 6]Ответ 4
lst = [4, 6, 2, 2, 6, 4, 4, 4] result = [r for s in sorted(set(lst), key=lst.index) for r in (a for a in lst if a == s)]Ответ 5
def frequency_sort(items): temp = [] sort_dict = {x: items.count(x) for x in items} for k, v in sorted(sort_dict.items(), key=lambda x: x[1], reverse=True): temp.extend([k] * v) return temp
Комментариев нет:
Отправить комментарий