我正在使用Python 3的attrgetter
模块中的operator
函数来对对象(命中)列表进行排序。每个对象都有12个属性,我的排序功能可以馈给它们中的任何一个,以便以任何需要的方式对列表进行排序。我对包含字符串排序感兴趣的属性。这是我代码中的相关代码段。
from operator import attrgetter
...
def sort_hits_by_attribute(hits, attribute, backwards = False):
"""Takes a lits of hits and sorts them by some attribute.
"""
return sorted(hits, key = attrgetter(attribute), reverse = backwards)
这里是“命中”对象及其属性的示例。
name: ...
entity_1: coffee cultivation
entity_2: ...
full_statement: ...
category: ...
rule: ...
syn_configs: ...
lex_conditions: ...
sentence_number: ...
close_call: False
message: ...
id: 119
如果我按属性entity_1
对对象列表进行排序,则在对象entity_1
字段以大写字母开头的实例之后,对上述对象进行 排序。 ,“咖啡”甚至“动物园”。
我想使用类似casefold()
之类的函数,以便大写字母在其小写字母的旁边和后面排序。但是,casefold()
仅对字符串有效,因此使用key = attrgetter(attribute).casefold()
返回AttributeError。
如何保留sort_hits_by_attribute()
的功能(即,按在函数调用期间传递的属性进行排序),但在执行此操作时强制Python使用不同的顺序{aAbBcCdDeE ...}?
答案 0 :(得分:0)
由于@KylePDavis,我找到了答案here,他提供了一种通用的解决方案,可以将属性作为参数传递。密钥是使用lambda
函数定义密钥。
我的代码现在如下所示。请注意输入检查,以验证(1)列表不为空,以及(2)感兴趣的属性是否确实是可以使用str
进行排序的类型(casefold()
)。
def sort_hits_by_attribute(hits, attribute, backwards=False):
"""Takes a lits of hits and sorts them by some attribute.
For instance, group duplicate relation hits together by sorting
on full_statement.
"""
if hits:
if isinstance(attrgetter(attribute)(hits[0]), str):
return sorted(hits,
key = lambda A: attrgetter(attribute)(A).casefold(),
reverse = backwards)
else:
return sorted(hits,
key = attrgetter(attribute),
reverse = backwards)
我没有将此问题标记为重复,因为引用的问题最喜欢的答案并不是专门针对这种情况的答案。