以前的解决方案侧重于字符串,其中数字与字母之间用破折号(对包含数字和字母的字符串排序)或另一个一致的分隔符(例如'_',python按字母顺序排序带有前导数字的字符串)分隔。与字母相比,数字通常处于相同的位置。这些是相对简单的列表,例如
l=['101-8', '101-8A', '101-9', '102-1', '103-4', '103-4B', '101-10', '101-11','103-10'] 或
l=['10_file','11_file','1_file','20_file','21_file','2_file']我需要分类如下:
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']如果用于排序的浮点数(带有前面的+或-符号)总是发生在相同的位置,“位置”意味着列表中的排序元素出现在列表中的索引中,这意味着排序元素出现在列表中的索引,而该索引是在某种一致的分隔符下拆分每个字符串元素的结果。
例如,这样的列表:
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‘处。
如果排序元素所在的索引(在nicelist中为2)是事先不知道的,那么如何实现类似的简单解决方案?
这个问题有许多越来越复杂的情况,例如浮点数发生在任意位置,当没有一致的分隔符时,在其他地方除了浮点数之前,还有混杂的'+'和'-'符号,以及不属于浮点数的数字。例如,
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']基本上,最终的任务将是找到一个优雅的解决方案(一行将是惊人的),对字符串元素列表进行排序,其中每个元素包含一个大小/长度和符号未知的浮点数(可以是正的,也可以是负的),并且可以出现在字符串中的任意位置,没有已知的一致分隔符。
谢谢你的想法!
发布于 2018-02-19 22:26:53
您只需要从每个字符串中提取float/int,以及符号(+或-),然后将提取的部分传递到float()函数和排序中。
所以我想出的正则表达式(regex101)是:
(\+|-)\d+(\.\d+)?因此,我们检查浮点数/int前面有一个小数点( + )或一个小数点( - ),然后匹配尽可能多的小数点(.),然后再匹配尽可能多的小数点(如果有小数点的话)。最后一部分(“只有当有”)是通过?实现的--意思是0或1出现。
因此,要将其应用于Python,使用您的列表l,并且已经运行了import re,您可以使用以下一行对其进行排序:
l.sort(key = lambda s: float(re.search('(\+|-)\d+(\.\d+)?', s).group()))在最后一个示例中,将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']发布于 2018-02-19 22:24:38
使用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’
上面的正则表达式与诸如-.0、-4.、+5.0、-3.e3、+5.2E-1等值相匹配。基本上,python中的任何有效浮点值都是可以识别的。这可能是你想要的,也可能不是你想要的,但我只是让你意识到。
https://stackoverflow.com/questions/48874786
复制相似问题