如何在sorted()中对元组elems应用关键函数?

时间:2013-09-27 10:24:55

标签: function sorting python-3.x tuples

我们知道这两个都适用于sorted():

sorted(['second', 'first', 'third'])
sorted([('first','second'), ('second', 'first'), ('first', 'third')])

通过对第二个进行排序,按字典顺序对元组进行比较;比较第一项;如果它们相同则比较第二项,依此类推。

但是如何在所有单个字符串(或其他任何其他字符串)上应用键函数以便对两个容器起作用并在第二种情况下递归地工作?假设func将'first'转换为3,'second'转换为1,将'third'转换为2.我想要这个结果:

['second', 'third', 'first']
[('second', 'first'), ('first','second'), ('first', 'third')]

我使用了这个函数作为键,但我不喜欢使用它进行类型检查,因为它只对字符串应用func而不是一般解决方案:

def recursively_apply_func_on_strings(target, func,
    fargs=(), fkwargs={}):
    if isinstance(target, str):
        return func(target, *fargs, **fkwargs)       
    result, f = [], recursively_apply_func_on_strings
    for elem in target:
        result.append(f(elem, func, fargs, fkwargs))
    return tuple(result)

sorted(sequence, key=lambda x: recursively_apply_string_func(x, func))

有更简洁的方法吗?

1 个答案:

答案 0 :(得分:1)

好吧,尽管我的评论不是这样说的,但我认为有一些可能的改进方法。

一个想法是让你的功能成为一个关键功能工厂。这样,您就不需要lambda来在sorted调用中使用额外的参数来应用它。

另一个想法是将func应用于所有不可迭代的值(加上字符串),使用Iterable模块中的抽象collections类型进行测试。

以下是一些代码:

from collections import Iterable

def recursive_key(func, fargs=(), fkwargs={}):
    def key_func(target):
        if isinstance(target, str) or not isinstance(target, Iterable):
            return func(target, *fargs, **fkwargs)       
        return tuple(key_func(item) for item in target)
    return key_func

你这样称呼它(按十六进制整数值排序,而不是字符串值):

sorted([('a', 'F'), ('A', 'd')], key=recursive_key(int, (16,)))

请注意,我们调用 recursive_key并且它的返回值(又名key_func)是作为key参数传递给{{1}的内容}}