Этот ответ в основном скопирован / вставлен из раздела примеров 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
поплавков, что очень тщательно .
Полное раскрытие, я автор нацорта.