Numerische Sortierung innerhalb alphanumerischer Zeichenketten

Häufig hat man eine Liste mit alphanumerische Zeichenketten (strings), die man sortieren möchte.
Die Standardsortierroutine von Python gibt aber oft nicht das gewünschte Ergebnis zurück, denn anstatt der natürlichen Folge 1, 2, 3, 10, 21, erhält man die Sortierung 1, 10, 2, 21, 3.

Mit dem folgenden Code-Snippet, der einen „key“ für die „sorted“-Funktion definiert, erhält man die gewünschte Sortierung:

import re


def alphanumeric_sort(alphanumeric_list):
    """Returns a given list in correct alphanumeric sort,
    e.g. 1, 2, 3, 10, 21 instead of 1, 10, 2, 21, 3

    :return sorted alphanumeric list
    """

    convert = lambda text: int(text) if text.isdigit() else text.lower()
    alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
    return sorted(alphanumeric_list, key=alphanum_key)

Der Methode wird eine Liste übergeben, und man erhält eine sortierte Liste in natürlicher Reihenfolge zurück.

Input:
input_list = ['alfa_1', 'alfa_21', 'alfa_3', 'alfa_10', 'alfa_2']
Output von sorted(input_list):
['alfa_1', 'alfa_10', 'alfa_2', 'alfa_21', 'alfa_3']
Output von sorted_alphanumeric(input_list):
['alfa_1', 'alfa_2', 'alfa_3', 'alfa_10', 'alfa_21']

Input:
input_list = ['alfa_1_beta', 'alfa_21_beta', 'alfa_3_beta', 'alfa_10_beta', 'alfa_2_beta']
Output von sorted(input_list):
['alfa_10_beta', 'alfa_1_beta', 'alfa_21_beta', 'alfa_2_beta', 'alfa_3_beta']
Output von sorted_alphanumeric(input_list):
['alfa_1_beta', 'alfa_2_beta', 'alfa_3_beta', 'alfa_10_beta', 'alfa_21_beta']

Input:
input_list = ['1_alfa', '21_alfa', '3_alfa', '10_alfa', '2_alfa']
Output von sorted(input_list):
['10_alfa', '1_alfa', '21_alfa', '2_alfa', '3_alfa']
Output von sorted_alphanumeric(input_list):
['1_alfa', '2_alfa', '3_alfa', '10_alfa', '21_alfa']

An den Beispielen lässt sich auch erkennen, dass es bei der Standardsortierung noch davon abhängt, wo der numerische Anteil im String steht. Daher erhält man unterschiedliche Ergebnisse.
Die neue Methode liefert immer das gleiche Ergebnis, egal ob der numerische Anteil im String, am Anfang oder am Ende steht.