1

I have a list of objects like below:

my_list = [LowPriorty(), HighPriority(), HighestPriority(), MediumPriority(), HighestPriority()]

These objects will have a custom defined order, e.g. I could define the order of highest priority to lowest priority like below:

HighestPriority() = should be closest to start of list
HighPriority() = should be second closest to start of the list
MiddlePriority() = should be third closest to start of the list
LowPriority() = should be fourth closest to start of the list
LowestPriority() = should be closest to end of the list

I want to re-order the list based on the priority structure I setup above, so I would expect the sorted list to look like below:

sorted_my_list = [HighestPriority(), HighestPriority(), HighPriority(), MediumPriority(), LowPriority()]

What is the best way to do this? The ordering is going to be based on the class type, but I need to be able to define which class is higher priority.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
KillerKode
  • 957
  • 1
  • 12
  • 31
  • Does this answer your question? [Making a python user-defined class sortable, hashable](https://stackoverflow.com/questions/7152497/making-a-python-user-defined-class-sortable-hashable) – jonrsharpe Aug 18 '22 at 10:43
  • Not quite, the __lt__ and __eq__ methods would be good if you were comparing a list containing the same class. But these are independent classes not related to each other. – KillerKode Aug 18 '22 at 11:13
  • Then how exactly _is_ the hierarchy to be determined? Maybe e.g. https://stackoverflow.com/q/14208256/3001761 is a better dupe. Right now the answerers are having to guess; give a [mre]. I'd also recommend reading https://docs.python.org/3/howto/sorting.html which covers various cases. – jonrsharpe Aug 18 '22 at 11:14
  • The hierarchy is defined based on the list order I define, like I put in my question. There is no way to actually compare the objects based on their attributes, as they are not related to each other in anyway. Instead we need to basically compare based on which class, e.g. ClassA is always higher priority than ClassB, etc. – KillerKode Aug 18 '22 at 11:18
  • That claim conflicts with the answer you've accepted, in which they _are_ compared by their attributes and are effectively related via the requirement to have a `priority`. – jonrsharpe Aug 18 '22 at 11:31
  • It doesn't, my point still stands. The answer involves first __adding__ attributes to the classes specifically for comparison, which is part of the solution. Again, even after adding these attributes specifically for comparison, I still wouldn't be able to use __lt__ or __eq__ because they are for comparing the same object types. – KillerKode Aug 18 '22 at 12:21
  • That's not true at all, even if the classes aren't otherwise related if adding to them is an option `__lt__` could e.g. be provided by a mix-in and compare anything with a `priority`. If you included the relevant context when asking it would be easier to provide good answers. – jonrsharpe Aug 18 '22 at 12:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/247377/discussion-between-killerkode-and-jonrsharpe). – KillerKode Aug 18 '22 at 21:04

2 Answers2

3

Another solution:

my_list = [
    LowPriorty(),
    HighPriority(),
    HighestPriority(),
    MediumPriority(),
    HighestPriority(),
]

hierarchy = [HighestPriority, HighPriority, MediumPriority, LowPriorty]

print(sorted(my_list, key=lambda o: hierarchy.index(type(o))))

Prints your sorted list.

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
2

You can set a priority for each class with a class variable, which you can later sort by:

class HighestPriority:
    priority = 1
    def __init__(self):
        pass # Other useful code here

class HighPriority:
    priority = 2
    def __init__(self):
        pass # Other useful code here

class MiddlePriority:
    priority = 3
    def __init__(self):
        pass # Other useful code here

And so on... Assuming you now have a list of objects from these classes, sorting them is simple:

result = sorted(list_of_objects, key=lambda x: x.priority)
Ofer Sadan
  • 11,391
  • 5
  • 38
  • 62