Python中PHP的natsort函数的类似功能(使用“自然顺序”算法排序列表)

24 投票
3 回答
21834 浏览
提问于 2025-04-15 21:02

我想知道在Python中有没有类似于PHP的natsort函数的东西?

l = ['image1.jpg', 'image15.jpg', 'image12.jpg', 'image3.jpg']
l.sort()

这个给出的结果是:

['image1.jpg', 'image12.jpg', 'image15.jpg', 'image3.jpg']

但我想要的结果是:

['image1.jpg', 'image3.jpg', 'image12.jpg', 'image15.jpg']

更新

这个解决方案是基于这个链接的。

def try_int(s):
    "Convert to integer if possible."
    try: return int(s)
    except: return s

def natsort_key(s):
    "Used internally to get a tuple by which s is sorted."
    import re
    return map(try_int, re.findall(r'(\d+|\D+)', s))

def natcmp(a, b):
    "Natural string comparison, case sensitive."
    return cmp(natsort_key(a), natsort_key(b))

def natcasecmp(a, b):
    "Natural string comparison, ignores case."
    return natcmp(a.lower(), b.lower())

l.sort(natcasecmp);

3 个回答

2

这个函数可以用作Python 2.x和3.x中sorted函数的key=参数:

def sortkey_natural(s):
    return tuple(int(part) if re.match(r'[0-9]+$', part) else part
                for part in re.split(r'([0-9]+)', s))
18

你可以在PyPI上查看这个第三方的natsort库:

>>> import natsort
>>> l = ['image1.jpg', 'image15.jpg', 'image12.jpg', 'image3.jpg']
>>> natsort.natsorted(l)
['image1.jpg', 'image3.jpg', 'image12.jpg', 'image15.jpg']

我得坦白一下,这个库是我写的。

52

这是我在自然排序算法问题下的一个回答:

import re
def natural_key(string_):
    """See https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/"""
    return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_)]

举个例子:

>>> L = ['image1.jpg', 'image15.jpg', 'image12.jpg', 'image3.jpg']
>>> sorted(L)
['image1.jpg', 'image12.jpg', 'image15.jpg', 'image3.jpg']
>>> sorted(L, key=natural_key)
['image1.jpg', 'image3.jpg', 'image12.jpg', 'image15.jpg']

为了支持Unicode字符串,应该使用.isdecimal()而不是.isdigit()。你可以在@phihag的评论中看到相关的例子。相关链接还有:如何揭示Unicode的数字值属性

在Python 2中,对于某些地区的字节字符串,.isdigit()也可能会失败(返回一个int()无法接受的值),例如在Windows的cp1252地区,'\xb2' ('²')

撰写回答