【问题标题】:Sorting a list of strings based on numeric order of numeric part根据数字部分的数字顺序对字符串列表进行排序
【发布时间】:2021-06-10 09:44:46
【问题描述】:

我有一个可能包含数字的字符串列表。我想按字母顺序对这个列表进行排序,但是每次字符串包含一个数字时,我都希望它按值排序。 例如,如果列表是

['a1a','b1a','a10a','a5b','a2a'], 

排序后的列表应该是

['a1a','a2a','a5b','a10a','b1a']

一般来说,我想把字符串中的每个数字(数字序列)当作一个特殊字符,它比任何字母都小,并且可以在数字上与其他数字进行比较。

是否有任何python函数可以紧凑地做到这一点?

【问题讨论】:

  • 你如何比较'ab1c''a1ef'
  • 假设数字小于字母,我会将字符“1”与字母“b”进行比较,并将“a1ef”放在“ab1c”之前。一般来说,我想将字符串中的每个数字视为一个特殊字符,它比任何字母都小,并且可以在数字上与其他数字进行比较。
  • 不能用mylist.sort()方法吗?
  • 不,排序会将 'a2a' 放在 'a10a' 之后,尽管 10 大于 2。

标签: python sorting


【解决方案1】:

您可以使用re 模块将每个字符串拆分为一个字符元组,并将数字分组为一个元素。像r'(\d+)|(.)' 这样的东西。这个正则表达式的好消息是它将分别返回数字组和非数字组。

作为一个简单的键,我们可以使用:

def key(x):
    # the tuple comparison will ensure that numbers come before letters
    return [(j, int(i)) if i != '' else (j, i)
        for i, j in re.findall(r'(\d+)|(.)', x)]

演示:

lst = ['a1a', 'a2a', 'a5b', 'a10a', 'b1a', 'abc']
print(sorted(lst, key=key)

给予:

['a1a', 'a2a', 'a5b', 'a10a', 'abc', 'b1a']

如果您想要更高效的处理,我们可以在闭包中只编译一次正则表达式

def build_key():
    rx = re.compile(r'(\d+)|(.)')
    def key(x):
        return [(j, int(i)) if i != '' else (j, i)
            for i, j in rx.findall(x)]
    return key

并以这种方式使用它:

sorted(lst, key=build_key())

当然给出相同的输出。

【讨论】:

    猜你喜欢
    • 2017-11-20
    • 1970-01-01
    • 2014-06-13
    • 2023-01-21
    • 2021-06-25
    • 1970-01-01
    • 2021-07-08
    • 2016-11-03
    • 1970-01-01
    相关资源
    最近更新 更多