Reputation: 6525
Here I am try to sort the list of strings based on the one string, Here my test cases,
First Case:
par_str = "abcd"
list_str = ['bb','ba','ab']
sorted(list_str, key=par_str)
Output: ['ab','ba','bb']
Second Case:
par_str = "bacd"
list_str = ['bb','ba','ab']
sorted(list_str, key=par_str)
Output: ['bb','ba','ab']
From the First case list order changed based on par_str
string. And Second test case the list order no change because it has same priority. So How to write above logic. I have tried but I am getting an error TypeError: 'str' object is not callable
Upvotes: 1
Views: 92
Reputation: 304175
>>> par_str = "abcd"
>>> list_str = ['bb','ba','ab']
>>>
>>> def key_func(s):
... return [par_str.index(i) for i in s]
...
>>> sorted(list_str, key=key_func)
['ab', 'ba', 'bb']
>>> par_str = "bacd"
>>> sorted(list_str, key=key_func)
['bb', 'ba', 'ab']
If par_str
is long enough it will be worthwhile using the helper dict
in @falsetru's answer.
It's preferable to use a full function definition rather than a lambda if you would like to be able to test your key function
Here is a little trick to make the key function really fast. (The dict is subtly different to @falsetru's)
>>> par_str = "abcd"
>>> list_str = ['bb','ba','ab']
>>> sorted(list_str, key=lambda s, trans={ord(c): i for i, c in enumerate(par_str)}:s.translate(trans))
['ab', 'ba', 'bb']
>>> par_str = "bacd"
>>> sorted(list_str, key=lambda s, trans={ord(c): i for i, c in enumerate(par_str)}:s.translate(trans))
['bb', 'ba', 'ab']
Upvotes: 1
Reputation: 369074
Make a mapping between characters and ranks, and use that information in key
function.
>>> par_str = "abcd"
>>> order = {c:i for i, c in enumerate(par_str)} # <------------
>>> order
{'a': 1, 'c': 2, 'b': 0, 'd': 3}
>>> list_str = ['bb','ba','ab']
>>> sorted(list_str, key=lambda s: [order[c] for c in s])
['ab', 'ba', 'bb']
>>> par_str = "bacd"
>>> order = {c:i for i, c in enumerate(par_str)} # <-----------
>>> order
{'a': 1, 'c': 2, 'b': 0, 'd': 3}
>>> list_str = ['bb','ba','ab']
>>> sorted(list_str, key=lambda s: [order[c] for c in s])
['bb', 'ba', 'ab']
Upvotes: 1