python排序负数和/或十进制字母数字字符串

标签 python sorting numbers decimal alphanumeric

我在对包含负数和/或十进制字母数字字符串的字符串列表进行排序时遇到问题。这是我目前所拥有的:

import re

format_ids = ["synopsys_SS_2v_-40c_SS.lib",
              "synopsys_SS_1v_-40c_SS.lib",
              "synopsys_SS_1.2v_-40c_SS.lib", 
              "synopsys_SS_1.4v_-40c_SS.lib",
              "synopsys_SS_2v_-40c_TT.lib",
              "synopsys_FF_3v_25c_FF.lib",
              "synopsys_TT_4v_125c_TT.lib",
              "synopsys_TT_1v_85c_TT.lib",
              "synopsys_TT_10v_85c_TT.lib",
              "synopsys_FF_3v_-40c_SS.lib",
              "synopsys_FF_3v_-40c_TT.lib"]

selector = r'.*(FF|TT|SS)_([-\.\d]+v)_([-\.\d]+c)_(FF|TT|SS).*'
#key = [2,1,3]
key = 2
produce_groups = False

if isinstance(key, int):
    key = [key]

convert = lambda text: float(text) if text.isdigit() else text
alphanum_key = lambda k: [convert(c) for c in re.split('([-.\d]+)', k)]
split_list = lambda name: tuple(alphanum_key(re.findall(selector,name)[0][i]) for i in key)
format_ids.sort(key=split_list)

print "\n".join(format_ids)

我期待以下输出(按第 3 个键排序):

synopsys_SS_2v_-40c_SS.lib
synopsys_SS_1v_-40c_SS.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-40c_TT.lib
synopsys_FF_3v_25c_FF.lib
synopsys_TT_1v_85c_TT.lib
synopsys_TT_10v_85c_TT.lib
synopsys_TT_4v_125c_TT.lib

但我得到以下信息(所有负数都列在最后):

synopsys_FF_3v_25c_FF.lib
synopsys_TT_1v_85c_TT.lib
synopsys_TT_10v_85c_TT.lib
synopsys_TT_4v_125c_TT.lib
synopsys_SS_2v_-40c_SS.lib
synopsys_SS_1v_-40c_SS.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-40c_TT.lib

现在,对于第二个键的小数(将键变量更改为 1 (key=1)),我得到:

synopsys_SS_1v_-40c_SS.lib
synopsys_TT_1v_85c_TT.lib
synopsys_SS_2v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_FF_3v_25c_FF.lib
synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-40c_TT.lib
synopsys_TT_4v_125c_TT.lib
synopsys_TT_10v_85c_TT.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib

期待:

synopsys_SS_1v_-40c_SS.lib
synopsys_TT_1v_85c_TT.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_2v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_FF_3v_25c_FF.lib
synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-40c_TT.lib
synopsys_TT_4v_125c_TT.lib
synopsys_TT_10v_85c_TT.lib

非常感谢任何建议。

编辑:我最终使用了 simpler method由@StephenRauch 描述:

import re
def sort_names(format_ids, selector, key=1):

    if isinstance(key, int):
        key = [key]

    SELECTOR_RE = re.compile(selector)

    def convert(x):
        try:
            return float(x[:-1])
        except ValueError:
            return x

    def sort_keys(key):
        def split_fid(x):
            x = SELECTOR_RE.split(x)
            return tuple([convert(x[i]) for i in key])
        return split_fid

    format_ids.sort(key=sort_keys(key))

format_ids = ["synopsys_SS_2v_-40c_SS.lib",
              "synopsys_SS_1v_-40c_SS.lib",
              "synopsys_SS_1.2v_-40c_SS.lib",
              "synopsys_SS_1.4v_-40c_SS.lib",
              "synopsys_SS_2v_-40c_TT.lib",
              "synopsys_FF_3v_25c_FF.lib",
              "synopsys_TT_4v_125c_TT.lib",
              "synopsys_TT_1v_85c_TT.lib",
              "synopsys_TT_10v_85c_TT.lib",
              "synopsys_FF_3v_-40c_SS.lib",
              "synopsys_FF_3v_-40c_TT.lib"]

selector = r'.*(FF|TT|SS)_([-\.\d]+v)_([-\.\d]+c)_(FF|TT|SS).*'
key = [2,1,3]

sort_names(format_ids,selector,key)

最佳答案

需要以不同的方式测试数字,并为 re.split() 提供了一个前导 '',这会导致 convert 例程中断。

固定代码:

key = [2,1,3]

def convert(x):
    try:
        return float(x)
    except ValueError:
        return x

alphanum_keys = lambda k: (convert(c) for c in re.split('([-.\d]+)', k))
alphanum_key = lambda k: [i for i in alphanum_keys(k) if i != ''][0]
split_list = lambda name: [
    alphanum_key(re.findall(selector, name)[0][i]) for i in key]
format_ids.sort(key=split_list)

备用(更简单)解决方案:

但是...所有这些 lambda 和正则表达式,都比您解决此问题所需的复杂得多。怎么样:

def sort_key(keys):

    def convert(x):
        try:
            return float(x[:-1])
        except ValueError:
            return x

    def f(x):
        x = x.split('_')
        return tuple([convert(x[i]) for i in keys])
    return f

format_ids.sort(key=sort_key([3, 2, 4]))

如何?

sort_keys() 返回函数 f()。这是传递给 sort() 以评估排序顺序的一个参数的函数。函数 f() 将使用传递给 sort_keys() 的键值,因为这些值是 available at the time f() is defined .这称为 closure .

结果:

synopsys_SS_1v_-40c_SS.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_2v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-40c_TT.lib
synopsys_FF_3v_25c_FF.lib
synopsys_TT_1v_85c_TT.lib
synopsys_TT_10v_85c_TT.lib
synopsys_TT_4v_125c_TT.lib

关于python排序负数和/或十进制字母数字字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44837419/

相关文章:

c - 将-1、0或1随机添加到C中的数字

python - 这 PyList_Append(list, Py_BuildValue(...)) 是否泄漏?

python - 使用 PyDrive (Python) 访问文件夹、子文件夹和子文件

python - 抓取括号内的元素

javascript - 日期排序 JavaScript

r - R中的排序列联表

javascript - 按正态分布(高斯分布)对数字数组进行排序

jQuery 从字符串中获取数字

python - 使用就地排序的 QuickSort

list - 如何检查列表中的所有数字是否都在稳步增加?