-2

我有一个文件名列表,其中一些只有文本,有的有文本和数字,有的全有。

例子:

[ 'mango_1.jpg', 'dog005.jpg', 'guru_2018_01_01.png', 'dog008.jpg', 'mango_6.jpg', 'guru_2018_5_23.png', 'dog01.png', 'mango_11.jpg', 'mango2.jpg', 'guru_2018_02_5.png', 'guru_2019_08_23.jpg', 'dog9.jpg', 'mango05.jpg' ]

我的代码是:

import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
    """ Sort the given list in the way that humans expect.
    """
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
    l.sort( key=alphanum_key )
    return print(l)

实际输出:

['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_1.jpg', 'mango_6.jpg', 'mango_11.jpg']

预期输出:

['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango5.jpg', 'mango_6.jpg', 'mango_11.jpg']

如何获得预期的输出?

4

2 回答 2

0

在这种情况下,您似乎对_字符没有任何意义,请修改您的代码以排除它

import re
## ref: https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
def sort_nicely( l ):
    """ Sort the given list in the way that humans expect.
    """
    convert = lambda text: int(text) if text.isdigit() else text
    alphanum_key = lambda key: [ convert(c.replace("_","")) for c in re.split('([0-9]+)', key) ]
    l.sort( key=alphanum_key )
    return print(l)
    ```
于 2020-02-05T14:17:00.160 回答
0

据我了解,您想根据每个文件名中可能存在的“文本”和“日期”进行排序。因此,首先您需要一个可以将文件名拆分为这两个组件的函数:

def split(n):
    # back-to-front, find first letter index
    for (i, c) in enumerate(reversed(n)):
        if not (c.isdigit() or c == '_'):
            break
    # proper (non-reversed) index
    i = len(n) - i
    # split into name and date
    (n, t) = (n[:i], n[i:])
    # split and remove extra underscores
    t = filter(bool, t.split('_'))
    # convert to integers and return
    return n, tuple(map(int, t))

然后你需要一个函数来删除文件名中任何不需要的部分(如扩展名):

import os
def parse(n):
    (n, e) = os.path.splitext(n)
    return split(n)

现在您可以简单地将其用作内置sorted函数中的键:

>>> sorted(l, key = parse)
['dog01.png', 'dog005.jpg', 'dog008.jpg', 'dog9.jpg', 'guru_2018_01_01.png', 'guru_2018_02_5.png', 'guru_2018_5_23.png', 'guru_2019_08_23.jpg', 'mango_1.jpg', 'mango2.jpg', 'mango05.jpg', 'mango_6.jpg', 'mango_11.jpg']
于 2020-02-05T14:32:10.900 回答