将methodcaller和attrgetter与已排序的

时间:2018-05-06 15:32:05

标签: python python-3.x sorting functional-programming nested

我想获得一个PosixPath对象列表,并根据相应的文件大小对其进行排序。我正在尝试使用排序函数。我想要用于排序的关键是object.stat().st_size,其中object是PosixPath对象,stat()返回os.stat_result对象,st_size是对应文件的大小到PosixPath对象。我知道如何使用operator.methodcalleroperator.attrgetter基于对象方法或对象属性进行排序,但我无法弄清楚如何使用{{1}返回的对象的属性}}

我尝试了以下和一些变体,但它不起作用:

methodcaller

2 个答案:

答案 0 :(得分:1)

它们并不意味着要结合起来。你应该使用lambda作为密钥:

from pathlib import Path
sorted(Path('.').glob('*.py'), key=lambda p: p.stat().st_size)

或者,如果要动态更改排序字段:

key_field = 'st_mtime'
sorted(Path('.').glob('*.py'), 
       key=lambda p: attrgetter(key_field)(p.stat()))

而且,如果你真的想使用methodcallerattrgetter,你可以这样做:

sorted(Path('.').glob('*.py'), key=lambda p: attrgetter('st_size')(methodcaller('stat')(p)))

答案 1 :(得分:1)

Function composition在Python中不是原生的。

应用逻辑的一种可读方式是使用直接而非功能性路径:

res = sorted(Path('.').glob('*.py'), key=lambda p: p.stat().st_size)

但是,有第三方库提供此功能,例如toolz

from toolz import compose
from operator import attrgetter, methodcaller

get_size = compose(attrgetter('st_size'), methodcaller('stat'))

res = sorted(Path('.').glob('*.py'), key=get_size)

在我看来,如果你想要一个功能性解决方案,你应该使用或编写一个组合高阶函数,如上所述,以确保你的代码可读。

相关:Nested lambda statements when sorting lists