如何在多个不同的位置有效地排序包含浮点数和前导+或符号的Python字符串

2024-05-14 16:08:31 发布

您现在位置:Python中文网/ 问答频道 /正文

以前的解决方案侧重于字符串,其中数字与字母之间用破折号(sorting strings containing numbers and letters)或另一个一致的分隔符(例如,'\',python sort strings with leading numbers alphabetically)隔开。数字与字母的位置通常相同。这些都是相对简单的列表,比如

l=['101-8', '101-8A', '101-9', '102-1', '103-4', '103-4B', '101-10', '101-11','103-10'] 

或者

^{pr2}$

我需要整理一下:

listfromhell=['a_+10.9.mrc','a_-10.0.mrc','a_-12.0_b.mrc','az_x_y_+60.13_a.hdf','bc_ab_+15.0_rst.mrc']

排序需要基于-或{}符号(包括符号)后面的数字。在

因此,上述列表的正确排序是:

listfromhell=['a_-12.0_b.mrc','a_-10.0.mrc','a_+10.9.mrc','bc_ab_+15.0_rst.mrc','az_x_y_+60.13_a.mrc']

如果用于排序的浮点数(带有前面的+-符号)总是出现在同一个位置,则类似于先前为更简单列表而提出的一行代码,其中“location”表示排序元素出现在列表中的索引,该索引是由于在某种一致的分隔符。在

例如,这样的列表:

nicelist=['a_b_-12.0_d.mrc','a_r_+10.9_t_z_y.mrc','c_a_-10.0.mrc','bc_ab_+15.0_rst.mrc','az_x_+60.13_a.mrc']

可以很容易地通过以下方式进行排序:

sorted(l, key=lambda s: float(s.split("_")[2].replace('.mrc',''))))

因为在使用一致分隔符'_'拆分每个字符串后,浮点数总是出现在索引“2”处

当排序元素出现的索引(2 in nicelist)事先未知时,如何实现类似的简单解决方案?在

这个问题有多种越来越复杂的情况,例如当浮点数出现在随机位置时,当没有一致的定界符时,当除了浮点数的前面之外,在其他地方还有混杂的'+'和{}符号,以及不是的混淆数字浮点数的一部分。E、 g

listfromhellandthensome=['a5-_-12.0b.mrc','a+101.9-.mrc','-a11_-10.0.mrc','b-c_ab_+15.0_rs+t.mrc','a + z_-x_y_+6.10334_a4.mrc']

基本上,最终的任务是找到一个优雅的解决方案(一行代码将是惊人的)排序字符串元素列表,其中每个元素包含一个大小/长度未知的单个浮点数和符号(可以是正的也可以是负的),并且可以出现在字符串中的任意位置,没有已知的一致分隔符

谢谢你的想法!在


Tags: 字符串元素列表ab排序字母符号数字
2条回答

您只需要从每个字符串中提取float/int,以及符号(+或{}),然后将提取的部分传递给float()函数并进行排序。在

所以我提出的正则表达式(regex101)是:

(\+|-)\d+(\.\d+)?

因此,我们检查float/int前面是否有+-,然后尽可能多地匹配小数点(.),然后尽可能多地匹配小数点后的小数点——只有在有小数点的情况下。最后一部分(“只有在存在的情况下”)是通过一个?-意思是0或{}出现来实现的。在

现在要将此应用于Python,使用您的列表l,并且已经运行了import re,您可以用这一行对它进行排序:

^{pr2}$

在最后一个例子中,l为:

['a5-_-12.0b.mrc', '-a11_-10.0.mrc', 'a + z_-x_y_+6.10334_a4.mrc', 'b-c_ab_+15.0_rs+t.mrc', 'a+101.9-.mrc']

我相信这是正确的!在


对于listfromhell示例,这实现了预期的输出:

['a_-12.0_b.mrc', 'a_-10.0.mrc', 'a_+10.9.mrc', 'bc_ab_+15.0_rst.mrc', 'az_x_y_+60.13_a.hdf']

使用regex拆分字符串:

import re

# taken from https://gist.github.com/smac89/bfefc0303c2aab6cac0b08055e195c55
regex = r'.*?([-+](?:\d+\.\d*|\.?\d+)(?:[eE][-+]?\d+)?).*'
compiled = re.compile(regex)

listfromhellandthensome=['a5-_-12.0b.mrc','a+101.9-.mrc','-a11_-10.0.mrc','b-c_ab_+15.0_rs+t.mrc','a + z_-x_y_+6.10334_a4.mrc']

print (sorted(listfromhellandthensome, key=lambda s: float(compiled.sub(r'\1', s))))

输出:

['a5-_-12.0b.mrc', '-a11_-10.0.mrc', 'a + z_-x_y_+6.10334_a4.mrc',
'b-c_ab_+15.0_rs+t.mrc', 'a+101.9-.mrc']

以上regex与诸如^{{cd1>}、^{cd2>}、^{cd3>}、^{cd4>}、^{{cd5>}等值匹配。基本上,python中的任何有效浮点值都可以识别。这也许不是你想要的,但我只是让你明白。

相关问题 更多 >

    热门问题