attrgetter:按对象属性排序时更改默认顺序
attrgetter: Altering Default Order When Sorting by Object Attribute
我正在使用 Python 3 的 operator
模块中的 attrgetter
函数来对对象列表(命中)进行排序。每个对象都有 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)
这是一个 "hit" 对象及其属性的示例。
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
字段以 an 开头的实例之后大写字母:例如 "Coffee" 甚至 "Zoo."
我想使用类似 casefold()
的函数,这样大写字母就会排在小写字母的旁边和后面。但是,casefold()
仅对字符串有效,因此使用 key = attrgetter(attribute).casefold()
returns 一个 AttributeError.
如何保留 sort_hits_by_attribute()
的功能——即按函数调用期间传入的属性排序——但强制 Python 使用不同的顺序 {aAbBcCdDeE...}这样做?
我找到了答案 here,感谢@KylePDavis,他提供了一个通用的解决方案,可以将属性作为参数传入。密钥是使用 lambda
函数定义密钥。
我的代码现在看起来如下。请注意输入检查以验证 (1) 列表不为空以及 (2) 感兴趣的属性是否确实属于可以使用 casefold()
.[=15 排序的类型 (str
) =]
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)
我没有将此问题标记为重复,因为引用的问题的最喜欢的答案并不是对这种情况特别重要的答案。
我正在使用 Python 3 的 operator
模块中的 attrgetter
函数来对对象列表(命中)进行排序。每个对象都有 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)
这是一个 "hit" 对象及其属性的示例。
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
字段以 an 开头的实例之后大写字母:例如 "Coffee" 甚至 "Zoo."
我想使用类似 casefold()
的函数,这样大写字母就会排在小写字母的旁边和后面。但是,casefold()
仅对字符串有效,因此使用 key = attrgetter(attribute).casefold()
returns 一个 AttributeError.
如何保留 sort_hits_by_attribute()
的功能——即按函数调用期间传入的属性排序——但强制 Python 使用不同的顺序 {aAbBcCdDeE...}这样做?
我找到了答案 here,感谢@KylePDavis,他提供了一个通用的解决方案,可以将属性作为参数传入。密钥是使用 lambda
函数定义密钥。
我的代码现在看起来如下。请注意输入检查以验证 (1) 列表不为空以及 (2) 感兴趣的属性是否确实属于可以使用 casefold()
.[=15 排序的类型 (str
) =]
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)
我没有将此问题标记为重复,因为引用的问题的最喜欢的答案并不是对这种情况特别重要的答案。