Как правильно реализовать именованные кортежи
Ревьюером было предложено использованием именованных кортежей для читабельности кода. Почитал статью посмотрел видео в ютубе, но пока трудно с пониманием реализацией. Я так понимаю в моем случае его надо прописывать в методе transformations, и первое что я должен создать класс и его атрибуты. Например Competitors = namedtuple('Competitors', 'name pi fi'), а дальше я должен через созданную переменную Competitors создать экземпляры класса переданные в метод transformations. А как это сделать туплю и не могу понять что делать.
В метод tranformations передается кортеж с такими данными (<имя>, <числовое значение>, <числовое значение>) и возвращает тот же кортеж только в другом порядке.
def partition(competitors, left, right):
if right <= left:
return
pivot = (left + right) // 2
part = competitors[pivot]
begin = left
end = right
while begin <= end:
while part > competitors[begin]:
begin += 1
while part < competitors[end]:
end -= 1
if begin <= end:
competitors[begin], competitors[end] = competitors[
end], competitors[begin]
begin += 1
end -= 1
partition(competitors, left, end)
partition(competitors, begin, right)
def transformations(competitors):
competitors[1] = - int(competitors[1])
competitors[2] = int(competitors[2])
return [competitors[1], competitors[2], competitors[0]]
def quick_sort(competitors):
partition(competitors, 0, len(competitors) - 1)
return [line[2] for line in competitors]
if __name__ == '__main__':
number = int(input())
competitors = [transformations(input().split()) for _ in range(number)]
result = quick_sort(competitors)
print(*result, sep="\n")
Ответы (2 шт):
Вот так я реализовал метод transformations
from collections import namedtuple
...
def transformations(competitors):
Competitor = namedtuple('Competitor', 'login number fine')
participant = Competitor(
competitors[0], - int(competitors[1]), int(competitors[2])
)
return participant.number, participant.fine, participant.login
Но время выполнения на некоторых тестах при этом увеличилось почти в 3 раза.
В вашем коде не хватает читабельности. Что такое line[2]? что там лежит?
Числа-индексы читателю (да и писателю тоже) ни о чем не говорят. Должны быть говорящие ключи. Теоретически может подойти словарь, namedtuple, класс (dataclass).
Словарь сразу плох - мутабельный и IDE не дает подсказки. В остальном - вопрос не про выбор, раз namedtuple, значит namedtuple
Заводим namedtuple (возьмем из collections, вы же используете его, а не из модуля typing)
Competitor = namedtuple('Competitor', 'login number fine')
и пусть transformations станет более читабельным. Вроде такого, я могу ошибаться, мне не хочется вчитываться что под индексами должно быть.
def transformations(competitor_data: list[str]) -> Competitor:
assert len(competitor_data) == 3
login, num, fine = competitor_data
return Competitor(login, -int(num), int(fine))
делать competitor_data как кортеж - имхо польза сомнительная, ведь по факту метод парсит сырой ввод в кортежи.
далее мы работаем уже с объектом Competitor, а значит улучшаем читабельность метода quick_sort
def quick_sort(competitors: list[Competitor]) -> list[str]:
partition(competitors, 0, len(competitors) - 1)
return [competitor.login for competitor in competitors]
сразу понятно, что возвращается список логинов, а не непонятный line[2] (опустим деталь, что этот метод вообще не должен возвращать логины, а только сортировать)
Метод partition. Там используются операции сравнения и там без 0.5 не разберешься как и что сравнивается.
Я как-то не вижу смысла сравнения "в лоб" и ожидал бы что сравнивается по какому-нибудь полю, например fine, но модифицировать partition для сравнения явных полей некрасиво. Лучше определить свои операции сравнения в Competitor - пусть сравнивает по полю fine
Поскольку это namedtuple из collections, то в нем нельзя определить методы сравнения прямо, но можно так
class Competitor(namedtuple('Competitor', 'login number fine')):
def __gt__(self, other):
return self.fine > other.fine
def __lt__(self, other):
return self.fine < other.fine
def __eq__(self, other):
return self.fine == other.fine