带有两位小数的数字字符串排序的问题

3

我有一组版本号,例如:

["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]

我希望将它们按从小到大的顺序排序。我发现可以使用sorted()函数来完成排序。这是我想到的函数:

def order(l):

    # Sorts numbers from smallest to largest
    orderedList = sorted(l)

    strList = ""

    for i in range(len(orderedList)):
        strList += orderedList[i]
        
        # Don't put a comma for the last loop
        if i < len(orderedList) - 1: 
            strList += ", "
    
    print(strList)

所以,

order(["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"])

目前的输出结果是:

0.1, 1.1.1, 1.11, 1.2, 1.2.1, 2, 2.0, 2.0.0

这看起来是正确的,但我需要它按不同的顺序排序。

我的期望输出结果是:

0.1, 1.1.1, 1.2, 1.2.1, 1.11, 2, 2.0, 2.0.0

换句话说,我需要告诉程序,1.11 就像 one.eleven,而不是十进制的 one.oneone,因此比 1.21.2.1 大。类似于 Minecraft 的版本控制系统;1.181.8.9 大,我需要函数按此方式排序。但是 sorted() 函数将其排序成 1.8.9 大于 1.18

有没有我错过的明显解决方案?

这比我预期的更复杂吗?

我是否需要创建自己的排序函数作为 sorted() 的替代品?

我是否可以使用 sorted() 中的 key 参数来构建自己的顺序?如果可以,如何实现?

提前感谢!


如果您可以接受使用其他库,有一个不错的库可以使用...请查看该帖子。 - Daniel Hao
2个回答

3
你需要的是真正称为“人类排序”的东西。而且有一个库可以实现此目的:
你只需要首先运行“pip install natsort”来获取该库。为什么要“重新发明轮子”而不是专注解决我们的“真正”问题呢?
import natsort
ans = natsort.natsorted(lst)
ans
['0.1', '1.1.1', '1.2', '1.2.1', '1.11', '2', '2.0', '2.0.0']

另一个例子

heights = '125 inches,11 inches,25 inches,2 inches,100 inches'
sort_heights = natsort.natsorted(heights.split(','))
sort_heights
['2 inches', '11 inches', '25 inches', '100 inches', '125 inches']

2

您希望进行排序,以便将版本号中的每个数字与同一位置上的另一个数字作为整数进行比较,因此只需按点拆分,映射到int,强制转换为排序关键字的tuple,然后您可以join该列表并避免使用那个for循环:

def order(lst):
    lst = sorted(lst, key=lambda x: tuple(map(int, x.split("."))))
    return ", ".join(lst)


print(order(["1.11", "2.0.0", "1.2", "2", "0.1", "1.2.1", "1.1.1", "2.0"]))
# 0.1, 1.1.1, 1.2, 1.2.1, 1.11, 2, 2.0, 2.0.0

这很聪明,谢谢! - proventus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接