Search code examples
pythonsortingtuplesalphanumericnatural-sort

Naturally sort a list of alpha-numeric tuples by the tuple's first element in Python


A previous stackoverflow question explains how to sort a list of strings alpha-numerically. I would like to sort a list of tuples alphanumerically by the tuple's first element.

Example 1:

>>> sort_naturally_tuple([('b', 0), ('0', 1), ('a', 2)])
[('0', 1), ('a', 2), ('b', 0)]

Example 2:

>>> sort_naturally_tuple([('b10', 0), ('0', 1), ('b9', 2)])
[('0', 1), ('b9', 2), ('b10', 0)]

Update: To emphasize the alphanumeric factor, please review example 2.


Solution

  • Using the second answer from the other question, generalized to support any method on item as the basis for getting the key:

    import re
    from operator import itemgetter
    
    def sorted_nicely(l, key):
        """ Sort the given iterable in the way that humans expect."""
        convert = lambda text: int(text) if text.isdigit() else text
        alphanum_key = lambda item: [ convert(c) for c in re.split('([0-9]+)', key(item)) ]
        return sorted(l, key = alphanum_key)
    
    
    print sorted_nicely([('b10', 0), ('0', 1), ('b9', 2)], itemgetter(0))
    

    This is exactly the same as that answer except generalized to use any callable as the operation on item. If you just wanted to do it on a string, you'd use lambda item: item, if you wanted to do it on a list, tuple, dict, or set, you'd use operator.itemgetter(key_or_index_you_want), or if you wanted to do it on a class instance you could use operator.attrgetter('attribute_name_you_want').

    It gives

    [('0', 1), ('b9', 2), ('b10', 0)]
    

    for your example #2.