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