dhana
dhana

Reputation: 6525

How to sort the list based on the string?

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

Answers (2)

John La Rooy
John La Rooy

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

falsetru
falsetru

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

Related Questions