简体   繁体   English

对包含带有 SI 前缀的数字的字符串列表进行排序

[英]Sort a list of strings that contain numbers with SI prefixes

I am trying to sort the following list:我正在尝试对以下列表进行排序:

['default.smt',
 'Setup 19k Hz.smt',
 'Setup 1k Hz.smt',
 'Setup 3 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 5k Hz.smt',
 'Setup 9k Hz.smt']

Where k is 1000, so for example 9k is 9000, and should appear before 19k which is 19000.其中k是 1000,例如9k是 9000,应该出现在19k之前,即 19000。

So I need my list to look like this:所以我需要我的列表看起来像这样:

['default.smt',
 'Setup 3 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 1k Hz.smt',
 'Setup 5k Hz.smt',
 'Setup 9k Hz.smt',
 'Setup 19k Hz.smt']

The 'default.smt' cell can either be first or last, I don't mind about that. 'default.smt'单元格可以是第一个或最后一个,我不介意。

How can I do this?我怎样才能做到这一点?

You can use regex inside a custom key function.您可以在自定义键 function 中使用正则表达式。 In the example I used a naive regex that will fail in some edge-cases, but you can adapt it.在示例中,我使用了一个简单的正则表达式,它在某些极端情况下会失败,但您可以调整它。

import re

regex = re.compile(r'(\d+)(k)?')

li = ['default.smt',
 'Setup 19k Hz.smt',
 'Setup 1k Hz.smt',
 'Setup 3 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 5k Hz.smt',
 'Setup 9k Hz.smt']

def magic(e):
    match = regex.findall(e)
    if not match:
        return -1
    num, k = int(match[0][0]), match[0][1]
    if k:
        return num * 1000
    return num

print(sorted(li, key=magic))

Outputs输出

['default.smt',
 'Setup 3 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 1k Hz.smt',
 'Setup 5k Hz.smt',
 'Setup 9k Hz.smt',
 'Setup 19k Hz.smt']

This answer is basically copy/pasted from the examples section of natsort 's documentation .这个答案基本上是从natsort文档的示例部分复制/粘贴的。 All I have done is change the specifics.我所做的只是改变细节。

>>> import re
>>> import natsort
>>>
>>> # Define how each unit will be transformed
>>> conversion_mapping = {
...         "k": 1000,     # kilo
...         "M": 1000000,  # mega
...         # Extend suffixes as you need
... }
>>>
>>> # This regular expression searches for numbers and units
>>> all_units = "|".join(conversion_mapping.keys())
>>> float_re = natsort.numeric_regex_chooser(natsort.FLOAT | natsort.SIGNED)
>>> unit_finder = re.compile(r"({})({})".format(float_re, all_units), re.IGNORECASE)
>>>
>>> def unit_replacer(matchobj):
...     """
...     Given a regex match object, return a replacement string where units are modified
...     """
...     number = matchobj.group(1)
...     unit = matchobj.group(2)
...     new_number = float(number) * conversion_mapping[unit]
...     return "{}".format(new_number)
...
>>> # Demo time!
>>> data = ['default.smt',
...  'Setup 19k Hz.smt',
...  'Setup 1k Hz.smt',
...  'Setup 3 Hz.smt',
...  'Setup 500 Hz.smt',
...  'Setup 55 Hz.smt',
...  'Setup 5k Hz.smt',
...  'Setup 9k Hz.smt']
>>> [unit_finder.sub(unit_replacer, x) for x in data]
['default.smt',
 'Setup 19000.0 Hz.smt',
 'Setup 1000.0 Hz.smt',
 'Setup 3 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 5000.0 Hz.smt',
 'Setup 9000.0 Hz.smt']
>>>
>>> natsort.natsorted(data, key=lambda x: unit_finder.sub(unit_replacer, x), alg=natsort.LOWERCASEFIRST)
['default.smt',
 'Setup 3 Hz.smt',
 'Setup 55 Hz.smt',
 'Setup 500 Hz.smt',
 'Setup 1k Hz.smt',
 'Setup 5k Hz.smt',
 'Setup 9k Hz.smt',
 'Setup 19k Hz.smt']

The advantage here is that not only does this use natsort 's robust algorithm, but you also get to use natsort 's regular expression definition of floats, which is very thorough .这里的好处是,这不仅使用natsort的健壮算法,而且您还可以使用natsort的浮点正则表达式定义,这是非常彻底的。

Full disclosure, I am the natsort author.完全披露,我是 natsort 作者。

I did it with the replace() function.我用replace() function 做到了。 You can make this code without import.您可以在不导入的情况下制作此代码。 Here is my code:这是我的代码:

    def sortList(list):

    sortedList = []
    finalList = []
    for elements in list:
        if elements == "default.smt":
            finalList.append(elements)
        else:
            elements = elements.replace("Setup ", "")
            elements = elements.replace("k", "000")
            elements = elements.replace("Hz.smt", "")
            sortedList.append(int(elements))
    sortedList.sort()
    for elements in sortedList:
        elements = str(elements).replace("000", "k")
        finalList.append("Setup " + str(elements) + " Hz.smt")
    return finalList


list = ['default.smt',
        'Setup 19k Hz.smt',
        'Setup 1k Hz.smt',
        'Setup 3 Hz.smt',
        'Setup 500 Hz.smt',
        'Setup 55 Hz.smt',
        'Setup 5k Hz.smt',
        'Setup 9k Hz.smt']
print(sortList(list))

The output is the following: output如下:

['default.smt', 'Setup 3 Hz.smt', 'Setup 55 Hz.smt', 'Setup 500 Hz.smt', 'Setup 1k Hz.smt', 'Setup 5k Hz.smt', 'Setup 9k Hz.smt', 'Setup 19k Hz.smt']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对包含数字和字符的字符串列表进行排序 - How to sort a list of strings which contain numbers and characters 在python中按数字对字符串列表进行排序 - Sort list of Strings by numbers in python 按 Python 中字符串中的数字对列表开头包含数字的字符串列表进行排序 - Sort a list of strings containing numbers at the start of the list by the numbers in the strings in Python 如何按字符串中的数字对字符串列表进行排序 - How to sort a list of strings by numbers in the string 如何对数字字符串的python列表进行排序 - How to sort python list of strings of numbers 如何对包含数字的字符串列表进行数字排序? - How to numerically sort list of strings containing numbers? 是否可以对代表菲律宾数字的字符串列表进行排序 - Is it possible to sort a list of strings that represents Filipino numbers Python - 有没有办法对包含日期和时间的字符串列表进行排序 - Python -Is there a way to sort a list of strings which contain a date and time within 对包含整数的字符串列表进行排序,同时忽略 python 中的空格 - Sort a list of strings that contain integers while ignoring white space in python 如何对python字符串列表进行排序,字符串末尾包含数字 - How to sort a python list of strings which contain a number in the end
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM