对使用 attrgetter 找到的属性使用函数进行排序

Sort using function on attribute found using attrgetter

我想对列表 foo_list 使用函数 foo_function 对列表中每个对象的属性 foo_attr 进行排序(所有对象的属性相同)。我试过使用下面的代码:

sorted(foo_list, key=foo_function(attrgetter('foo_attr')))

但是,我收到以下错误:

AttributeError: 'operator.attrgetter' object has no attribute foo_attr

编辑: 更新说明。我复制了排序代码,它使用了operator.attrgetter。根据答案,很明显我的简单需求不需要 operator.attrgetter。

我想你要找的是:

sorted(foo_list, key=lambda foo: foo_function(foo.foo_attr))

就是说,我不确定这个 attrgetter 在哪里发挥作用。如果它为您获得 foo_attr,那么您可以尝试使用:

sorted(foo_list, key=lambda foo: foo_function(attrgetter(foo)))

如果你想应用额外的功能而不是仅仅获取属性,最短的方法是使用lambda表达式:

sorted(foo_list, key=lambda x: foo_function(getattr(x, foo_attr)))

另一方面,如果您的属性名称始终相同(问题中不清楚),它将变为:

sorted(foo_list, key=lambda x: foo_function(x.foo_attr))

attrgetter 调用 returns 你是一个可调用对象,你应该将你的原始对象传递给它,以便返回你想要的属性:

>>> operator.attrgetter("upper")("")
<built-in method upper of str object at 0x7f86baa82508>

在您的情况下,您正在将此可调用对象传递给 foo_function,但是 foo_function 无法获取要在何处应用 attrgetter 的原始对象;

最直接的做法是放置一个 lambda,并明确地 在调用 foo_function:

之前检索表达式的属性
sorted(foo_list, key=lambda obj: foo_function(attrgetter(foo_attr)(obj)))

其实更直接的是干脆跳过attrgetter,直接用 getattr 内置 - 这很可能是您想要的:

sorted(foo_list, key=lambda obj: foo_function(getattr(obj, foo_attr))) 

而且,如果你真的想使用 attrgetter,如果你把它放在任何循环之外会更有效 - 所以它只定义一次并重复使用很多次 - 如果你不这样做在一个循环中,它没有实际用途,但会损害 getattr.

的可读性
getter = operator.attrgetter(foo_attr)
for  list_ in my_lists:
    results.append(sorted(list_, key=lambda obj: foo_function(getter(obj)))