1-Python - natsort

before

之前有个学生问我一个Windows环境下文件排序的问题,他的需求是这样的:
首先,在Windows的资源管理器中,有一批word文件,按照文件名排序,长这样:

然后,他想使用Python读取这个文件夹内所有的文件,并且顺序跟Windows的资源管理器中文件排序顺序一样。
我一琢磨,这不是根据字符串排序么,那还不简单?随手写了个示例:

import os
import copy

path = r'D:\downloads'


def c_sort(file_path):
    file_list = os.listdir(file_path)
    tmp1, tmp2 = copy.deepcopy(file_list), copy.deepcopy(file_list)
    tmp1.sort()
    tmp2 = sorted(tmp2)
    print(tmp1)
    print(tmp2)


c_sort(path)
"""
[
    'A公司业务部会议纪要(20200328).docx', 
    'A子公司业务部会议纪要-2021年1月24日.docx', 
    'A子公司业务部会议纪要-2021年3月6日.docx', 
    'A子公司业务部会议纪要-2022年1月12日.docx', 
    'A子公司业务部会议纪要-2022年1月25日.docx', 
    'A子公司业务部会议纪要(20200306).docx'
]
[
    'A公司业务部会议纪要(20200328).docx', 
    'A子公司业务部会议纪要-2021年1月24日.docx', 
    'A子公司业务部会议纪要-2021年3月6日.docx', 
    'A子公司业务部会议纪要-2022年1月12日.docx', 
    'A子公司业务部会议纪要-2022年1月25日.docx', 
    'A子公司业务部会议纪要(20200306).docx'
]
"""

但结果不符合预期,看来Python的list.sort和sorted的排序规则都和Windows资源管理器中的不符。

那就研究吧。

自然排序

通过查资料,Windows Explorer 文件排序使用的算法是被 Microsoft 官方称其为 Numerical Sorting 的算法,而在网络中常见的称呼是 Natural Sorting,姑且称之为自然排序。其实现方法也很简介,首先将字符串切分,分为全数字字符串与其他,再各部分一一对应比较,若皆为全数字字符串,则比较其值,否则按字符比较。
当然了,这里不在展开关于自然排序的Python实现了,这就跑题了。
我们知道了Python的list.sort和sorted实现不了自然排序,那么我们肯定面向谷歌解决问题了啊。

natsort

经查,在Python中可以使用natsort这个三方库来实现自然排序。
下载:

pip install natsort
# 我用的是8.1.0版本的
pip install natsort==8.1.0

在我们的需求中,看看能否解决问题:

from natsort import natsorted, os_sorted
from natsort import ns

path = r'D:\downloads'


def c_sort(file_path):
    file_list = os.listdir(file_path)
    tmp1, tmp2, tmp3, tmp4 = copy.deepcopy(file_list), copy.deepcopy(file_list), copy.deepcopy(
        file_list), copy.deepcopy(file_list)
    tmp1.sort()
    tmp2 = sorted(tmp2)
    # 起初,我查询的是下面这个解决方案,但它不是完全跟 Windows Explorer 的排序规则一致
    tmp3 = natsorted(tmp3, alg=ns.PATH)
    # 后来,又查询到了下面的解决方案,看结果是符合我们的需求的
    tmp4 = os_sorted(tmp4)
    print(tmp1)
    print(tmp2)
    print(tmp3)
    print(tmp4)


c_sort(path)
"""
['A公司业务部会议纪要(20200328).docx', 'A子公司业务部会议纪要-2021年1月24日.docx', 'A子公司业务部会议纪要-2021年3月6日.docx', 'A子公司业务部会议纪要-2022年1月12日.docx', 'A子公司业务部会议纪要-2022年1月25日.docx', 'A子公司业务部会议纪要(20200306).docx']
['A公司业务部会议纪要(20200328).docx', 'A子公司业务部会议纪要-2021年1月24日.docx', 'A子公司业务部会议纪要-2021年3月6日.docx', 'A子公司业务部会议纪要-2022年1月12日.docx', 'A子公司业务部会议纪要-2022年1月25日.docx', 'A子公司业务部会议纪要(20200306).docx']
['A公司业务部会议纪要(20200328).docx', 'A子公司业务部会议纪要-2021年1月24日.docx', 'A子公司业务部会议纪要-2021年3月6日.docx', 'A子公司业务部会议纪要-2022年1月12日.docx', 'A子公司业务部会议纪要-2022年1月25日.docx', 'A子公司业务部会议纪要(20200306).docx']
['A公司业务部会议纪要(20200328).docx', 'A子公司业务部会议纪要(20200306).docx', 'A子公司业务部会议纪要-2021年1月24日.docx', 'A子公司业务部会议纪要-2021年3月6日.docx', 'A子公司业务部会议纪要-2022年1月12日.docx', 'A子公司业务部会议纪要-2022年1月25日.docx']
"""

所以,最终,我们选择使用os_sorted来实现需求,并且达到预期。
而关于os_sorted,来看它官档的解释。
官档链接:https://natsort.readthedocs.io/en/8.1.0/api.html#os-sorted
重点:

On Windows, this will sort with the same order as Windows Explorer.

大致说在 Windows 上,这将按照与 Windows 资源管理器相同的顺序进行排序。这正好契合我们的需求啊。

参考:
https://natsort.readthedocs.io/en/8.1.0/api.html#os-sorted
https://www.learnfk.com/question/python/4836710.html
https://seven332.github.io/algorithm/2017/09/25/natural-sorting.html
https://wikichi.icu/wiki/Natural_sort_order
https://blog.csdn.net/qq_38463737/article/details/107840086

posted @ 2022-04-14 11:48  听雨危楼  阅读(898)  评论(0编辑  收藏  举报