首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python 3.x对列表中包含数字和字母的文件名进行排序

Python 3.x对列表中包含数字和字母的文件名进行排序
EN

Stack Overflow用户
提问于 2018-06-12 14:30:33
回答 2查看 55关注 0票数 1

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

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
\\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资源管理器显示的理想输出。

代码语言:javascript
复制
\\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

任何想法都将是一个很大的帮助。提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2018-06-12 14:41:17

如果您希望根据数字字符串的值对其进行排序,则应该使用它们的整数值,因为字符串是按字面顺序排序的,这意味着例如,字符串10小于2

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

代码语言:javascript
复制
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中,我们假设我们的正则表达式总是有匹配的,而没有处理任何可能的异常和/或考虑其他因素进行排序。处理这类情况的正确方法是使用try-except,以便以适当的方式处理不同的异常。

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

代码语言:javascript
复制
In [21]: def keyfunc(item):
    ...:     try:
    ...:         return int(re.search(r'-(\d+)[^-]*$', item).group(1))
    ...:     except AttributeError:
    ...:         return item
票数 3
EN

Stack Overflow用户

发布于 2018-06-12 15:40:18

下面是一个关键函数,它应该能够处理或多或少的任何字符串:

代码语言:javascript
复制
>>> import itertools
>>> 
>>> def key_fun(s):
...     return (*(("",) if s and s[0].isdecimal() else ()), *(int(''.join(g)) if k else ''.join(g) for k, g in itertools.groupby(s, str.isdecimal)),)

Demo (添加了一些随机字符串,不遵循模式):

代码语言:javascript
复制
>>> pprint(sorted(list_of_dwg + ['', '45', 'e'], key=key_fun))
['',
 '45',
 '\\\\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',
 'e']

下面是key函数的作用。它按十进制/非十进制分组,并转换十进制块。一个陷阱是,我们必须确保我们总是从相同类型的块开始,因为Python3不喜欢比较数字和字符串。当第一个字符是小数时,我选择在前面加上一个空字符串。因此,所有以数字开头的内容都会排在所有以非数字开头的内容之前。

代码语言:javascript
复制
>>> key_fun(list_of_dwg[0])
('\\\\pc_name\\AHL-', 4604, '-', 2, '-', 10, '.dwg')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50810572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档