代码之家  ›  专栏  ›  技术社区  ›  Emre Sevinç

Python将“u11词组1000.wav”排序在“u11词组101.wav”之前;我怎样才能克服这个问题?

  •  6
  • Emre Sevinç  · 技术社区  · 15 年前

    我正在win32上运行python2.5(r25:51908,2006年9月19日,09:52:17)[MSC v.1310 32位(英特尔)]

    当我问Python的时候

    >>> "u11-Phrase 099.wav" <  "u11-Phrase 1000.wav"
    True
    

    那很好。当我问

    >>> "u11-Phrase 100.wav" <  "u11-Phrase 1000.wav"
    True
    

    但是 当我问

    >>> "u11-Phrase 101.wav" <  "u11-Phrase 1000.wav"
    False
    

    所以根据Python,“u11词组100.wav”在“u11词组1000.wav”之前,但“u11词组101.wav”在“u11词组1000.wav”之后!这对我来说是个问题,因为我正试图编写一个文件重命名程序,这种排序破坏了功能。

    我能做些什么来克服这个问题?我应该编写自己的cmp函数并测试边缘情况,还是有更简单的快捷方式来提供我想要的排序?

    另一方面,如果我修改字符串,例如

    >>> "u11-Phrase 0101.wav" <  "u11-Phrase 1000.wav"
    True
    

    但是,这些字符串来自目录的文件列表,例如:

    files = glob.glob('*.wav')
    files.sort()
    for file in files:
        ...
    

    所以我不想在glob创建字符串之后对其进行外科手术。不,我也不想更改文件夹中的原始文件名。

    有什么提示吗?

    2 回复  |  直到 15 年前
        1
  •  16
  •   Ned Batchelder    15 年前

    你在找什么 human sorting .

        2
  •  9
  •   Martin Geisler    15 年前

    import re
    
    def k(s):
        return [w.isdigit() and int(w) or w for w in re.split(r'(\d+)', s)]
    
    files = ["u11-Phrase 099.wav", "u11-Phrase 1000.wav", "u11-Phrase 100.wav"]
    
    print files
    print sorted(files, key=k)
    

    它给出以下输出:

    ['u11-Phrase 099.wav', 'u11-Phrase 1000.wav', 'u11-Phrase 100.wav']
    ['u11-Phrase 099.wav', 'u11-Phrase 100.wav', 'u11-Phrase 1000.wav']
    

    这个 k

    >>> k('u11-Phrase 099.wav')
    ['u', 11, '-Phrase ', 99, '.wav']
    

    然后我们使用Python知道如何对列表进行排序的事实——它通过逐个比较每个元素来对列表进行排序。最终的结果是

    >>> k('u11-Phrase 99.wav') < k('u11-Phrase 100.wav')
    True
    

    鉴于

    >>> 'u11-Phrase 99.wav' < 'u11-Phrase 100.wav'
    False
    

    你已经发现了。