sfmagic.org Rewrite: Humane Dict Sorting

18:43 Sun 23 Dec 2007
[, , ]

Progress hasn’t been significant since yesterday, I haven’t had that much time. Right now I’m at the point of reading in parameters from the query string (easy) and looking for the most efficient way to use SQLAlchemy’s SQL Expressions to construct constraining select statements based on those parameters (not quite so easy for me, given that my lack of knowledge about SQLAlchemy makes ‘most efficient’ a difficult bar to know I’ve reached). Along the way, I got distracted and amalgamated some other people’s answers to get a useful code snippet.

I was sorting a list of dictionaries, and wanted to sort by alphanumeric values in one of the keys, but ran into the “lack of a human sort” problem, e.g. the values a1, a2, a3, a10, a11 would be sorted as a1, a10, a11, a2, a3 instead of the first, human-expected, way. So I took an answer from Ned Batchelder’s blog, and then found a more concise Python 2.5 version in the comments (‘Toothy’ is the submitter) and combined that with the standard decorate-sort-undecorate method so that I had this:

def sort_lists_of_dicts_nicely(undecorated, sort_key):
    """ Sort the lists of dicts in a human way."""
    decorated = [(dict_[sort_key], dict_) for dict_ in undecorated]
    convert = lambda text: int(text) if text.isdigit() else text 
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key[0]) ] 
    result = [dict_ for (key, dict_) in decorated]
    return result

I haven’t tested it too extensively, but it works for me so far, and seems like the kind of thing that’ll come in handy in future (I feel convinced that I’ll find some use for it in the sfmagic.org rewrite).

Leave a Reply