我们知道这两个都适用于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))
有更简洁的方法吗?
答案 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}的内容}}