Reputation: 33
I'm having an issue with sorting a list that contains a dict. Currently I am sorting it by a key called 'title' with the following line:
list.sort(key=operator.itemgetter('title'))
The problem with this is that some of my data gets sorted looking like this:
title_text #49
title_text #5
title_text #50
How would I go about sorting it in a way that is more friendly for human consumption while still maintaining the title sort?
Upvotes: 3
Views: 1009
Reputation: 879701
You are looking for human sorting.
import re
# Source: http://nedbatchelder.com/blog/200712/human_sorting.html
# Author: Ned Batchelder
def tryint(s):
try:
return int(s)
except:
return s
def alphanum_key(s):
""" Turn a string into a list of string and number chunks.
"z23a" -> ["z", 23, "a"]
"""
return [ tryint(c) for c in re.split('([0-9]+)', s) ]
def sort_nicely(l):
""" Sort the given list in the way that humans expect.
"""
l.sort(key=alphanum_key)
data=[
'title_text #49',
'title_text #5',
'title_text #50']
sort_nicely(data)
print(data)
# ['title_text #5', 'title_text #49', 'title_text #50']
Edit: If your data
is a list of dicts then:
data=[{'title': 'title_text #49', 'x':0},
{'title':'title_text #5', 'x':10},
{'title': 'title_text #50','x':20}]
data.sort(key=lambda x: alphanum_key(x['title']))
# [{'x': 10, 'title': 'title_text #5'}, {'x': 0, 'title': 'title_text #49'}, {'x': 20, 'title': 'title_text #50'}]
Upvotes: 4
Reputation: 212000
You'll have to parse that integer from the title manually. This function will do it.
def parse_title_num(title):
val = 0
try:
val = int(title.rsplit('#')[-1])
except ValueError:
pass
return val
list.sort(key=lambda x: parse_title_num(x['title'])
Upvotes: 0
Reputation: 308206
You're looking for a Natural Sort. Start here:
Python analog of natsort function (sort a list using a "natural order" algorithm)
Upvotes: 2