Сортированный список с объектами Python - более эффективный способ? - PullRequest
0 голосов
/ 06 ноября 2018

Я делаю задание для начинающих в Python и спрашиваю себя, есть ли способ краткого описания этого кода, который не создает список в классе . Нужно отсортировать список по всем параметрам по названию, возрасту, виду и наоборот.

Так что это работает, но безобразно:

def sortAnimal(llist):
    while True:
        print("\nChoose which parameter to sort: \n")
        print("1. Name\n2. Age\n3. Species\n")
        choice = int(input("Choice:"))
        print("\n")

        if choice == 1:
            print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
            sortedList = sorted(llist, key=lambda animal: animal.name)
            for obj in sortedList:
                print(obj)

            if input("\To reverse the list press enter. Otherwise press m + enter") == "":
                print("\n")
                print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
                sortedList = sorted(llist, key=lambda animal: animal.name, reverse= True)
                for obj in sortedList:
                    print(obj)
            else:
                pass

        elif choice == 2:
            # same code as option 1 but with animal.age
            pass

        elif choice == 3:
            #same code as option 1 but with animal.species
            pass

        if input("\To sort again press enter, back to menu press m + enter") == "":
            continue
        else:
            break

Я думал, что какая-то функция вроде этой, но она тоже не работает:

def sortPrintAnimal(parameter, llist):
    while True:
        sortedList = sorted(llist, key=lambda animal: animal.parameter)
        print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
        for obj in sortedList:
            print(obj)

        if input("If you want to reverse the list press enter. Back to menu press m + enter: ") == "":
            # reversing the list
            pass
        else:
            break

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Как насчет использования getattr(obj,attr), которое предназначено для этого?

def sortAnimals(animals, key='name'):
    return sorted(animals, key=lambda animal: getattr(animal,key))


def attr(choice):
    return {
        1: "name",
        2: "age",
        3: "species"
    }[choice]


def display_animals(animals):
    print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
    for obj in animals:
        print(obj)


def main(animals):
    while True:
        print("\nChoose which parameter to sort: \n")
        print("1. Name\n2. Age\n3. Species\n")
        choice = int(input("Choice:"))
        try:
            sorted_animals = sortAnimals(animals, attr(choice))
        except KeyError:
            print("Invalid Choice {}".format(choice))
            continue
        display_animals(sorted_animals)

        if not input("To reverse the list press enter. Otherwise press m + enter"):
            sorted_animals.reverse()
            display_animals(sorted_animals)

        if input("To sort again press enter, back to menu press m + enter"):
            break

main(animals_list)

Как вы упомянули эффективный способ , сохранение отсортированного списка для дальнейшего использования поможет, если у вас большой список

from collections import defaultdict
def main(animals):
    sort_map = defaultdict(dict)

    def _sorted_map(key, r_flag=False):
        if key not in sort_map:
            sort_map[key][False] = sortAnimals(animals, key)
        if r_flag and r_flag not in sort_map[key]:
            sort_map[key][True] = list(reversed(sort_map[key][False]))
        return sort_map[key][r_flag]


    while True:

        print("\nChoose which parameter to sort: \n")
        print("1. Name\n2. Age\n3. Species\n")
        choice = int(input("Choice:"))

        try:
            animal_attr = attr(choice)
        except KeyError:
            print("Invalid Choice {}".format(choice))
            continue

        sorted_animals = _sorted_map(animal_attr)
        display_animals(sorted_animals)

        if not input("To reverse the list press enter. Otherwise press m + enter"):
            sorted_animals = _sorted_map(animal_attr, True)
            display_animals(sorted_animals)

        if input("To sort again press enter, back to menu press m + enter"):
            break
0 голосов
/ 06 ноября 2018

Вы можете использовать словарь, в котором ключи являются вариантами выбора, а значения являются функциями (лямбдами), которые будут использоваться в качестве ключей, например:

def sortAnimal(llist):
    while True:
        print("\nChoose which parameter to sort: \n")
        print("1. Name\n2. Age\n3. Species\n")
        choice = int(input("Choice:"))
        print("\n")

        choices = {1: lambda animal: animal.name, 2: lambda animal: animal.age, 3: lambda animal: animal.species}

        print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
        sortedList = sorted(llist, key=choices[choice])
        for obj in sortedList:
            print(obj)

        if input("\To reverse the list press enter. Otherwise press m + enter") == "":
            print("\n")
            print("{:7s} {:7s} {:7s} {:7s}".format("Name:", "Age:", "Species:", "Gender:"))
            sortedList = sorted(llist, key=choices[choice], reverse=True)
            for obj in sortedList:
                print(obj)
            else:
                pass

        if input("\To sort again press enter, back to menu press m + enter") == "":
            continue
        else:
            break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...