是否有内置的字符串自然排序函数?
24 个回答
145
这是一个更符合Python风格的版本,来自Mark Byer的回答:
import re
def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
return [int(text) if text.isdigit() else text.lower()
for text in _nsre.split(s)]
现在这个函数可以作为关键字在任何使用它的函数中使用,比如 list.sort
、sorted
、max
等等。
作为一个lambda表达式:
lambda s: [int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', s)]
完整可复现的示例代码:
import re
natsort = lambda s: [int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', s)]
L = ["a1", "a10", "a11", "a2", "a22", "a3"]
print(sorted(L, key=natsort))
# ['a1', 'a2', 'a3', 'a10', 'a11', 'a22']
263
试试这个:
import re
def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(l, key=alphanum_key)
输出结果:
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
这段代码是从这里改编过来的:为人类排序:自然排序顺序。
373
在PyPI上有一个第三方库叫做 natsort(顺便说一下,我是这个库的作者)。对于你的情况,你可以选择以下任意一种方法:
>>> from natsort import natsorted, ns
>>> x = ['Elm11', 'Elm12', 'Elm2', 'elm0', 'elm1', 'elm10', 'elm13', 'elm9']
>>> natsorted(x, key=lambda y: y.lower())
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
>>> natsorted(x, alg=ns.IGNORECASE) # or alg=ns.IC
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
你需要注意的是,natsort
使用了一种通用的算法,所以它应该能处理你输入的几乎所有内容。如果你想了解更多关于为什么选择这个库而不是自己写一个函数的信息,可以查看natsort
文档中的工作原理页面,特别是特殊情况随处可见!这一部分。
如果你需要一个排序关键字而不是排序函数,可以使用下面的任意公式。
>>> from natsort import natsort_keygen, ns
>>> l1 = ['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
>>> l2 = l1[:]
>>> natsort_key1 = natsort_keygen(key=lambda y: y.lower())
>>> l1.sort(key=natsort_key1)
>>> l1
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
>>> natsort_key2 = natsort_keygen(alg=ns.IGNORECASE)
>>> l2.sort(key=natsort_key2)
>>> l2
['elm0', 'elm1', 'Elm2', 'elm9', 'elm10', 'Elm11', 'Elm12', 'elm13']
更新于2020年11月
因为一个常见的请求/问题是“如何像Windows资源管理器那样排序?”(或者你操作系统的文件浏览器),从natsort
版本7.1.0开始,有一个叫做os_sorted
的函数可以做到这一点。在Windows上,它会按照Windows资源管理器的顺序进行排序,而在其他操作系统上,它应该会像本地文件系统浏览器那样排序。
>>> from natsort import os_sorted
>>> os_sorted(list_of_paths)
# your paths sorted like your file system browser
对于需要排序关键字的用户,可以使用os_sort_keygen
(或者如果你只需要默认值,可以使用os_sort_key
)。
注意 - 在使用这个函数之前,请阅读API文档,以了解其限制和如何获得最佳结果。