Zak
Zak

Reputation: 49

Complicated sorting in Python

I need to sort a list of strings.

However, I do not want to sort it using the first character, so I cannot use .sort()

I have a list:

records = ["Bibble - 1300 / 2000",
"Jim Foo - 900 / 2000",
"Bibble - 1600 / 2000",
"Bibble - 1000 / 2000"]

I want to sort by their score out of 2000. I want an output that looks something like this:

>>> Jim Foo - 900 / 2000
Bibble - 1000 / 2000
Bibble - 1300 / 2000
Bibble - 1600 / 2000

In the example above, I sorted it by smallest to largest. I also want to know how I would sort this list biggest score to smallest score.

I've tried .sort(), but It's nothing like what I want. .sort() sorts it with the first character which I do not want:

>>> records.sort()
>>> records
['Bibble - 1000 / 2000', 'Bibble - 1300 / 2000', 'Bibble - 1600 / 2000', 'Jim Foo - 900 / 2000']
>>> 

Is there anyway of doing this, possibly in regular expression?

Is it also possible, so if i were to add more scores into the list I would still be able to sort it this way?

Upvotes: 2

Views: 179

Answers (5)

Kasravnd
Kasravnd

Reputation: 107297

You can use sorted function with a proper key and use re.split :

>>> import re
>>> sorted(records,key=lambda x:int(re.split(r'[-/]',x)[1].strip()))
['John Smith - 900 / 2000',
 'Bob Foo - 1000 / 2000', 
 'Bob Foo - 1300 / 2000', 
 'Bob Foo - 1600 / 2000']

The sorted function sort your list based on its key function, and your key split your elements with re.split with function as following :

re.split(r'[-/]',x)

the pattern [-/] split your string based on - or /.

for example :

>>> re.split(r'[-/]',"Bob Foo - 1600 / 2000")
['Bob Foo ', ' 1600 ', ' 2000']

and then you need to strip() to remove the leading and trailing spaces. then convert to int and sort your list based on that value!

Upvotes: 3

Jason Hu
Jason Hu

Reputation: 6333

>>> import re
>>> records = ["Bob Foo - 1300 / 2000",
"John Smith - 900 / 2000",
"Bob Foo - 1600 / 2000",
"Bob Foo - 1000 / 2000"]
>>> def get_score(s):
    m = re.match(r'.* - (\d+) / 2000', s)
    return 0 if m is None else int(m.group(1))

>>> sorted(records, key=get_score)
['John Smith - 900 / 2000', 'Bob Foo - 1000 / 2000', 'Bob Foo - 1300 / 2000', 'Bob Foo - 1600 / 2000']

get_score will calculate the key of each record, and sort or sorted will sort records according to this value.

Upvotes: 0

Jan Buchar
Jan Buchar

Reputation: 1322

Use the key attribute of the sort method:

import re
records.sort(key = lambda x: int(re.split('[-/]', x)[1]))

re.split splits x into parts whenewer it encounters a - or / character - that's what the [-/] expression stands for. Then we select the second part, convert it to an integer and use this value for sorting.

Upvotes: 0

iced
iced

Reputation: 1572

  1. sort accepts optional key parameter. E.g. if you want to sort int list by power of number you can do something like [-3, 2, 1].sort(key=lambda x: x *x)

  2. I'm pretty sure you can write function which extracts number 1000 from "Boo Foo - 1000 / 2000". Hint: use split.

Upvotes: -2

ferhatelmas
ferhatelmas

Reputation: 3978

def f(e):
    a, b = map(float, e.split('-')[1].split('/'))
    return a / b

records.sort(key=f)

Upvotes: 0

Related Questions