Reputation: 13
I am doing a beginners task in Python and wondering if there is a way to concise this code that is not to create a list in a class. Need to sort the list in all the parameters name, age, species, and in reverse.
So this works but is ugly:
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
I thought some kind of function like this but hasn't work either:
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
Upvotes: 0
Views: 89
Reputation: 975
How about using getattr(obj,attr)
which is meant for this ?
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)
As you mentioned efficient way, storing the sorted list for further use would help if you have large 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
Upvotes: 2
Reputation: 61910
You could use a dictionary where the keys are the choices and values are the functions (lambdas) to be used as keys, for example:
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
Upvotes: 0