(You've changed your question to wanting to do it with strings instead of with objects, so this example is with strings.)
Use the index of each string in predicate list to provide the key
on which to sort your given list:
>>> wanted_order = ['BODY.H', 'BODY.M', 'BODY.VL', 'WHL0.H']
>>> got_list = ['WHL0.H', 'BODY.H', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'BODY.M']
>>> sorted(got_list, key=lambda s: wanted_order.index)
['BODY.H', 'BODY.M', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'WHL0.H']
Note that I've added a few extra duplicate items in got_list
to show how it would work with generic input and more than one of each.
Btw, if there will always be just these 4 objects, why not just create a list with these 4?
Also, if a string is missing from your predicate, you'll get an error. So maybe put that in a function (rather than a lambda) and catch that error if it occurs, and return another value.
Edit:
For the object version of what you wanted, you would use s.name
for the key and predicate (and of course, wanted_order
has the names of objects):
>>> sorted(got_list, key=lambda s: wanted_order.index(s.name))
Edit 2:
To handle items in got_list
which don't have a 'name' in wanted_order
:
>>> def predicated_key(item):
... wanted_order = ['BODY.H', 'BODY.M', 'BODY.VL', 'WHL0.H']
... # put wanted_order in global scope if you prefer instead of here
... try:
... return wanted_order.index(item) # or item.name in your case
... except ValueError:
... return len(wanted_order) # since this will be higher than the
... # index of the any item on the list
...
>>> got_list = ['WHL0.H', 'BODY.H', 'something', 'BODY.VL',
... 'something else', 'BODY.VL', 'WHL0.H', 'BODY.M']
>>> sorted(got_list, key=predicated_key)
['BODY.H', 'BODY.M', 'BODY.VL', 'BODY.VL', 'WHL0.H', 'WHL0.H', 'something', 'something else']