英字と数字の両方を含む文字列を「ファイリング キャビネット」のようなものにする簡単な方法はありますか?
つまり、次のようなリストです。
[aa2, ab2, bb1, bc1, ab3, aa3, ba2, ba1, aa1, ac1, bb2, bb3, ab1]
にソートされます
[aa1, aa2, aa3, ab1, ab2, ab3, ac1, ba1, ba2, bb1, bb2, bb3, bc1]
それらを個々のキャラクターに分解し、各セットをソートしてから再構築するスクリプトのアイデアがありますが、それは難しい方法のようです. :-)
これがうまく機能する最終的なコードです。Experts Exchange D0t k0m の pepr と、質問が殺される前に回答してくれた jamylak に感謝します。組み込みの並べ替えは、並べ替えの数値部分を処理できません。つまり、数値を語彙的にソートします...
[aa1, aa11, aa111, aa2, aa3, ba1, ba11, ba2]
... それ以外の ...
[aa1, aa2, aa3, aa11, aa111, ba1, ba2, ba11]
したがって、ジャムラックのコードのこのバリエーションは美しく機能します...
def lexinumericalsort(_list):
def _key(item):
# pattern will split strings and letters up to 8 times (intended for device file names)
pattern = ('([a-zA-Z]{0,})(\d{0,})') * 8
try:
result = re.match(pattern, item).groups()
result = list(result)
for no, val in enumerate(result):
if val is '':
result.pop(no) # Remove blanks
try:
# Convert to integer if possible
result[no] = int(result[no])
except ValueError, e:
pass #silence if fails (leaves as character)
return result
except AttributeError, e:
e = ("functions.lexinumericalsort:\n" +
"Unable to resolve list into pattern matched groups.\n" +
str(e))
print e
return None
return sorted(_list, key = _key)