0

I have a list like this:

a = ['1', '3', '02', 'WF2', 'WF5', 'WF01']

and I want to sort like this:

a = ['1', '02', '3', 'WF01', 'WF2', 'WF5']

Using something like this:

def sortby(id):
    if 'WF' not in id and id.isdigit():
        return int(id)
    elif 'WF' in id.upper():
        return float('inf')

a.sort(key=sortby)

I can sort the integers without 'WF' prefix but I don't know how to sort the ones prefixed with 'WF' on its own.

Do I need to use double sorting, i.e. sort again and sort only the ones with prefix 'WF' and assign -Inf to all the other entries without 'WF' prefix? Any idea?

EDIT:

def sortby(id):
    if 'WF' not in id.upper():
        return int(id)
    return float('inf')

def sortby2(id):
    if 'WF' not in id.upper():
        return float('-inf')
    return int(id.replace('WF', ''))

a.sort(key=sortby)
a.sort(key=sortby2)

but it's not really nice...

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
tim
  • 9,896
  • 20
  • 81
  • 137

4 Answers4

6

Return pair of bool and int. bool will specify whether the item starts with WF and second item will be the actual integer value.

>>> lst = ['1', '3', '02', 'WF2', 'WF5', 'WF01']

>>> def key(item):
...     return item.startswith('WF'), int(item.lstrip('WF'))
...

>>> sorted(lst, key=key)
['1', '02', '3', 'WF01', 'WF2', 'WF5']
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Yours looks a bit nicer, though Scott wrote the concept faster -> hence I will accept his answer. But thanks as well :) – tim Jun 20 '17 at 14:06
  • It's not about he is faster, it's about what solution is better to use, so next time people open this thread knows which answer was more preferable. You can still upvote Scott's answer, but choose the one, that you are sticking with for your problem. – user1767754 Jun 20 '17 at 14:08
3

Just return a pair as a key, the first based on the presence or absence of "WF", the second on the number:

def sortby(id):
    if 'WF' not in id and id.isdigit():
        return (0,int(id))
    elif 'WF' in id.upper():
        return (1,int(id[2:]))
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • Thanks, that does the trick :) I knew there had to be something nice to manage those two groups but didn't think of using tuples this way. – tim Jun 20 '17 at 14:05
2

You could always do this:

a.sort(key=lambda x: (x[0] == "W", int(x.replace("WF", ""))))
gold_cy
  • 13,648
  • 3
  • 23
  • 45
Tané Tachyon
  • 1,092
  • 8
  • 11
2

Sort on a tuple checking if string does not start with 'WF' (priority) and then the int value:

a.sort(key=lambda x: (x.startswith('WF'), int(x.strip('WF'))))       
print(a)
#['1', '02', '3', 'WF01', 'WF2', 'WF5']
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139