tim
tim

Reputation: 10176

Sort List in Python but keep groups with prefix together

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...

Upvotes: 0

Views: 418

Answers (4)

Tané Tachyon
Tané Tachyon

Reputation: 1112

You could always do this:

a.sort(key=lambda x: (x[0] == "W", int(x.replace("WF", ""))))

Upvotes: 2

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250961

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']

Upvotes: 6

Moses Koledoye
Moses Koledoye

Reputation: 78556

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']

Upvotes: 2

Scott Hunter
Scott Hunter

Reputation: 49803

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:]))

Upvotes: 3

Related Questions