-2

英字と数字の両方を含む文字列を「ファイリング キャビネット」のようなものにする簡単な方法はありますか?

つまり、次のようなリストです。

[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)
4

1 に答える 1

1
>>> sorted("aa2, ab2, bb1, bc1, ab3, aa3, ba2, ba1, aa1, ac1, bb2, bb3, ab1".split(', '))
['aa1', 'aa2', 'aa3', 'ab1', 'ab2', 'ab3', 'ac1', 'ba1', 'ba2', 'bb1', 'bb2', 'bb3', 'bc1']

多分あなたはこれを意味しますが:

>>> items = ['a11', 'a2']
>>> sorted(items)
['a11', 'a2']

sorted が機能しない場所。正規表現パターンを使用してデータを照合し、key関数を渡すだけですsorted

>>> import re
>>> def key(item):
        g = re.match(r'([a-zA-Z]+)(\d+)', item).groups()
        return g[0], int(g[1])

>>> sorted(items, key=key)
['a2', 'a11']
于 2013-05-07T11:18:17.727 に答える