首页 > 解决方案 > Python 3.x 对列表中包含数字和字母的文件名进行排序

问题描述

我有以下 python 代码来对文件名列表进行排序

list_of_dwg = [
    r'\\pc_name\AHL-4604-0002-10.dwg',
    r'\\pc_name\AHL-4604-0002-11A.dwg',
    r'\\pc_name\AHL-4604-0002-4.dwg',
    r'\\pc_name\AHL-4604-0002-1_FRONT COVER.dwg',
    r'\\pc_name\AHL-4604-0002-2_MASTER LIST.dwg',
    r'\\pc_name\AHL-4604-0002-3_LEGEND LIST.dwg',

]

list_of_dwg_sorted = sorted(list_of_dwg)

for dwg in list_of_dwg_sorted:
    print(dwg)

当我执行代码时,输​​出将如下所示

\\pc_name\AHL-4604-0002-10.dwg
\\pc_name\AHL-4604-0002-11A.dwg
\\pc_name\AHL-4604-0002-1_FRONT COVER.dwg
\\pc_name\AHL-4604-0002-2_MASTER LIST.dwg
\\pc_name\AHL-4604-0002-3_LEGEND LIST.dwg
\\pc_name\AHL-4604-0002-4.dwg

但这是我基于 Windows 资源管理器显示的理想输出

\\pc_name\AHL-4604-0002-1_FRONT COVER.dwg
\\pc_name\AHL-4604-0002-2_MASTER LIST.dwg
\\pc_name\AHL-4604-0002-3_LEGEND LIST.dwg
\\pc_name\AHL-4604-0002-4.dwg
\\pc_name\AHL-4604-0002-10.dwg
\\pc_name\AHL-4604-0002-11A.dwg

任何想法都会有很大帮助。提前致谢!

标签: pythonpython-3.xlistsorting

解决方案


如果要根据数字字符串的值对数字字符串进行排序,则应使用它们的整数值,因为字符串按字面意思排序,这意味着例如字符串10小于2.

sorted()函数接受一个关键函数,您可以使用该函数来告诉sorted您如何对项目进行排序。在这种情况下,我们可以使用正则表达式来查找文件名中的最新数字,并使用其整数值对项目进行排序。

In [18]: import re

In [19]: def keyfunc(item):
    ...:     return int(re.search(r'-(\d+)[^-]*$', item).group(1))
    ...: 
    ...: 

In [20]: sorted(list_of_dwg, key=keyfunc)
Out[20]: 
['\\\\pc_name\\AHL-4604-0002-1_FRONT COVER.dwg',
 '\\\\pc_name\\AHL-4604-0002-2_MASTER LIST.dwg',
 '\\\\pc_name\\AHL-4604-0002-3_LEGEND LIST.dwg',
 '\\\\pc_name\\AHL-4604-0002-4.dwg',
 '\\\\pc_name\\AHL-4604-0002-10.dwg',
 '\\\\pc_name\\AHL-4604-0002-11A.dwg']

正如你所看到的,keyfunc我们假设我们的正则表达式总是有一个匹配项,而不处理任何可能的异常和/或考虑其他因素进行排序。处理这类情况的正确方法是使用 atry-except以便以正确的方式处理不同的异常。

举个例子,假设我们想要按照默认值对项目进行排序,以防我们的正则表达式在文件名末尾找不到预期的整数。在这种情况下,代码将返回AttributeError,因为re.search()将返回 None 并且 None 对象没有该group()属性。我们可以简单地处理这种情况:

In [21]: def keyfunc(item):
    ...:     try:
    ...:         return int(re.search(r'-(\d+)[^-]*$', item).group(1))
    ...:     except AttributeError:
    ...:         return item

推荐阅读