1

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

4
  • 3
    The key argument in sorted must be a callable, as in not a string. Commented Feb 25, 2014 at 5:48
  • What is the actual size of par_str? Commented Feb 25, 2014 at 6:00
  • @AshwiniChaudhary My actual string is "a-z". Commented Feb 25, 2014 at 6:02
  • @dhana in sorted(list_str, key=par_str), key=par_str is wrong Commented Feb 25, 2014 at 6:06

2 Answers 2

1

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']
Sign up to request clarification or add additional context in comments.

4 Comments

@dhana which line you don't understand. it is sorted on the basis of list of numbers. Very char is mapped to a number using order as list.
@GrijeshChauhan I didn't understand sorted method.
@dhana, The return value of the key function is used as comparison keys.
@dhana try >>> [1, 2, 3] < [1, 3, 3] on your system. Also try: >>> [order[c] for c in s]
1
>>> 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']

1 Comment

Thanks for your answer +1 for you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.