#python #python-3.x #sorting
#python #python-3.x #сортировка
Вопрос:
Мне нужно отсортировать строку запроса по различным параметрам. Например:
[url]/handler?sort=-key1,key2
Теперь сортировка выполняется в списке dicts в метаданных каждого dict следующим образом:
sorted(results_list, key=lambda obj:[(-obj["metadata"][x[0]] if x[1] == "desc" else obj["metadata"][x[0]]) for x in sort])
Параметры извлекаются из моего обработчика и передаются менеджеру логики для обработки сортировки. Этот код написан на python 3. Я хочу сделать этот механизм сортировки более расширяемым. В настоящее время это не позволит выполнять какую-либо сортировку, которая:
- Вне области действия свойства метаданных.
- не число (например, сортировка по алфавиту).
Я должен сказать, что я изучил ответы здесь и увидел, что многие из них предлагают переопределить функцию cmp и, по сути, воссоздать мой собственный модуль сортировки с нуля. Я не думаю, что либо то, что я ищу, не было сделано раньше, либо что это заслуживает такой реализации. Я могу ошибаться. Мы всегда учимся.
Итак, как мне следует переработать этот код, чтобы он был более расширяемым?
Ответ №1:
Что-то вроде этого:
вы должны иметь возможность передавать список SortInstruction
через свой API ( handler
). get_sorted_list
позаботится о фактической сортировке.
from typing import NamedTuple
lst = [{'meta':{'k':12},'k1': 66,'k2': 'jack'},
{'meta':{'k':99},'k1': 656,'k2': 'zoo'},
{'meta':{'k':134},'k1': 166,'k2': 'dan'}]
class SortInstruction(NamedTuple):
in_meta_data: bool
reverse: bool
field_name: str
def get_sorted_list(sort_instructions):
result = lst
for si in sort_instructions:
result = sorted(result, key = lambda x : x[si.field_name] if not si.in_meta_data else x['meta'][si.field_name] , reverse = si.reverse)
return result
sorted_list = get_sorted_list([SortInstruction(True,False,'k'),SortInstruction(False,False,'k1')])
for entry in sorted_list:
print(entry)
Ответ №2:
Чтобы сделать код более читаемым и простым в обслуживании, вы хотели бы расширить логику сортировки и дизайн НАДЕЖНЫМ образом.
Я бы посоветовал:
Handler
преобразует параметры из URL вcontext
объект, который содержит их все.Handler
передаетcontext
объектLogicManager
, который определяет, какой список сортировать и каким способом.LogicManager
отправьте список для сортировки и способ сортировки, как первоначально описано в URL, наSorter
, который сортирует списки, как описано.Таким образом, у каждого класса есть свое единственное предложение, и код проще поддерживать.
Тем не менее, вы можете масштабировать сортировку, добавив большеSorter
потоков или микросервисов.