Skip to content Skip to sidebar Skip to footer

Python Sort By Custom {key:order} Pair

I currently have code that, given a list, splits the names by the regexp in the selector (user defined) and sorts by the key (location - also user defined). The key can be a list

Solution 1:

I would call what you are trying to do here: Category Ordering. The dictionary you are passing in shows how to order certain fields. But what your dictionary does not, because it can not, show is how to order the fields. Python dicts are un-ordered on the keys. I would suggest keeping the meaning of the key field regardless of whether or not you pass in the dict which shows the category ordering.

Code:

As to how to make use of the information in the category_order, I think you need to change the convert() routine to something like:

def convert(i, x):
    if i in category_order:
        return category_order[i].index(x)
    try:
        return float(x[:-1])
    except ValueError:
        return x

Called like:

return tuple([convert(i, fields[i]) for i in key])

Full Routine:

def sort_names(format_ids, selector, key=1, category_order=None):

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

    if category_order is None:
        category_order = {}

    SELECTOR_RE = re.compile(selector)

    def convert(i, x):
        if i in category_order:
            return category_order[i].index(x)
        try:
            return float(x[:-1])
        except ValueError:
            return x

    def sort_keys():
        def split_fid(fid):
            fields = SELECTOR_RE.findall(fid)[0]
            return tuple([convert(i, fields[i]) for i in key])
        return split_fid

    result = list(format_ids)
    result.sort(key=sort_keys())
    return result

Test Code:

fids = ["synopsys_SS_2v_-40c_FF.lib",
        "synopsys_SS_1v_-40c_TT.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"]

se = r'.*(FF|TT|SS)_([-\.\d]+v)_([-\.\d]+c)_(FF|TT|SS).*'
k = [0, 3]
fo = {
      0: ['FF', 'TT', 'SS'],
      3: ['SS', 'TT', 'FF']
     }

print('\n'.join(sort_names(fids, se, k, fo)))

Results:

synopsys_FF_3v_-40c_SS.lib
synopsys_FF_3v_-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_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_1v_-40c_TT.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_SS_2v_-40c_FF.lib

Alternate Sort Key Results:

print('\n'.join(sort_names(fids, se, [2, 1, 3], fo)))

Gives:

synopsys_SS_1v_-40c_TT.lib
synopsys_SS_1.2v_-40c_SS.lib
synopsys_SS_1.4v_-40c_SS.lib
synopsys_SS_2v_-40c_TT.lib
synopsys_SS_2v_-40c_FF.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

Post a Comment for "Python Sort By Custom {key:order} Pair"