5

I have a class of this type

class Challenge():
  difficulty = Field(type=float)
  category = Field(type=str)

and I have a list of Challenge objects that I want to sort in a custom way: I want to order by difficulty with a custom order, and then per each difficulty I want to sort the objects by category, with a different custom order per each difficulty.

I already have a dict with as keys the ordered difficulties, and for each difficulty the ordered list of categories. I need to apply this ordering to my list and I don't know how to apply those criteria to sorting.

I reached this point:

found_challenges.sort(key=lambda x: (x.difficulty, x.category))

Obviously this doesn't sort by the way I want to sort. How can I apply those custom criteria to list sorting?

Example:

ch_1 = Challenge(difficulty=1.0, category='one')
ch_2 = Challenge(difficulty=1.0, category='two')
ch_3 = Challenge(difficulty=2.0, category='one')
ch_4 = Challenge(difficulty=2.0, category='two')

and the ordering dictionary is

{
   2.0: ['one', 'two'],
   1.0: ['two', 'one']
}

so the ordering should be:

[ch_3, ch_4, ch_2, ch_1]
Gianclè Monna
  • 387
  • 1
  • 5
  • 12

1 Answers1

2

Almost there:

found_challenges.sort(key=lambda x: (-x.difficulty, ordering_dict[x.difficulty].index(x.category)))

So the second key is the index of the category in the respective difficulty list. If you want to reverse the order on that just add a - sign.

If your difficulties are not just monotonic, note The order of keys in dictionaries. You can only depend on the insertion order from Python 3.7. In prior versions, if you want to index the keys you need an OrderedDict.

kabanus
  • 24,623
  • 6
  • 41
  • 74
  • 2
    Done! I had also to respect the order of insertion of the keys of `ordering_dict` dictionary, so I achieved my purpose in this way: `found_challenges.sort(key=lambda x: (list(ordering_dict.keys()).index(x.difficulty), ordering_dict[x.difficulty].index(x.category.value)))` – Gianclè Monna Oct 08 '19 at 09:27