按键对Python列表排序,同时检查字符串或浮点数?

1 投票
3 回答
3648 浏览
提问于 2025-04-15 12:42

好的,我有一个这样的列表(这是一些示例数据):

data = {"NAME": "James", "RANK": "3.0", "NUM": "27.5" ... }

现在,如果我运行类似这样的代码:

sortby = "NAME" //this gets passed to the function, hence why I am using a variable sortby instead
data.sort(key=itemgetter(sortby))

我得到的字符串会按照字母顺序正确排序。

但是,当“sortby”是浮点数值(比如RANK或NUM或其他)时,排序又是按照字母顺序进行的,而不是数字顺序,所以我的排序结果看起来像这样:

0.441
101.404
107.558
107.558
108.48
108.945
11.195
12.143
12.801
131.73

这显然是错的。

那么,我该如何进行这样的排序(在速度和资源/计算方面尽可能高效),但又能在处理浮点数时将其转换为浮点数,而在处理字符串时保持为字符串……这样做可能吗?而且,不,去掉列表中浮点数值的引号不是一个选项——我无法控制源列表,不幸的是(我知道,这本来是个简单的解决办法)。

3 个回答

0

虽然比直接传一个字段名要多说一些,但这也是一种选择:

sort_by_name = lambda x: x['name']
sort_by_rank = lambda x: float(x['RANK'])
# etc...

data.sort(key=sort_by_rank)

如果你的数据比你发的要复杂得多,你可能需要一个单独的字典,把字段名和数据类型对应起来,然后再写一个工厂函数,用来生成适合放在 list.sort()key 参数里的排序器。

4

如果你不能正确保存你的数据(比如把小数保存为浮点数),就会出现像下面这样的情况:

sorters = { "NAME" : itemgetter("NAME"), 
            "RANK" : lambda x: float(x["RANK"]),
            "NUM" : lambda x: float(x["NUM"])
}

data.sort(key=sorters[sortby])
7

如果你想要一个通用的函数,可以作为参数传递给 sort(key=XXX),那么这里有一个可以用的例子,还有测试代码:

DATA = [
    { 'name' : 'A', 'value' : '10.0' },
    { 'name' : 'B', 'value' : '2.0' },
]

def get_attr(name):
    def inner_func(o):
        try:
            rv = float(o[name])
        except ValueError:
            rv = o[name]
        return rv
    return inner_func

for attrname in ('name', 'value'):
    DATA.sort(key=get_attr(attrname))
    print "%r-sorted: %s" % (attrname, DATA)

当你运行上面的脚本时,你会得到:

'name'-sorted: [{'name': 'A', 'value': '10.0'}, {'name': 'B', 'value': '2.0'}]
'value'-sorted: [{'name': 'B', 'value': '2.0'}, {'name': 'A', 'value': '10.0'}]

撰写回答