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