Сортировка списка строк, содержащих числа с префиксом SI - PullRequest
0 голосов
/ 02 августа 2020

Я пытаюсь отсортировать следующий список:

['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']

Где k равно 1000, поэтому, например, 9k равно 9000 и должно появиться перед 19k, которое равно 19000.

Итак, мне нужно, чтобы мой список выглядел так:

['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']

Ячейка 'default.smt' может быть первой или последней, я не против.

Как я могу это сделать?

Ответы [ 3 ]

2 голосов
/ 02 августа 2020

Вы можете использовать регулярное выражение внутри пользовательской ключевой функции. В этом примере я использовал наивное регулярное выражение, которое не работает в некоторых крайних случаях, но вы можете его адаптировать.

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))

Выходы

['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']
0 голосов
/ 03 августа 2020

Этот ответ в основном скопирован / вставлен из раздела примеров natsort документации . Все, что я сделал, это изменил специфику.

>>> 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']

Преимущество здесь в том, что при этом не только используется надежный алгоритм natsort, но вы также можете использовать определение регулярного выражения natsort поплавков, что очень тщательно .

Полное раскрытие, я автор нацорта.

0 голосов
/ 02 августа 2020

Я сделал это с помощью функции replace(). Вы можете сделать этот код без импорта. Вот мой код:

    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))

Результат следующий:

['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']
...