按对象属性从列表中删除重复项的最佳方法

bgu*_*ach 10 python functional-programming

我有一个对象列表,我想以一种方式过滤列表,因此每个属性值只有一个出现.

例如,假设我有三个对象

obj1.my_attr = 'a'
obj2.my_attr = 'b'
obj3.my_attr = 'b'

obj_list = [obj1, obj2, obj3]
Run Code Online (Sandbox Code Playgroud)

最后,我想得到[obj1, obj2].实际上顺序并不重要,所以[obj1, obj3]完全一样好.

首先,我想到了典型的命令式笨重方式,如下所示:

record = set()
result = []

for obj in obj_list:
    if obj.my_attr not in record:
        record.add(obj.my_attr)
        result.append(obj)
Run Code Online (Sandbox Code Playgroud)

然后,我将其与字典匹配,使用键覆盖任何先前的条目,最后提取值:

result = {obj.my_attr: obj for obj in obj_list}.values() 
Run Code Online (Sandbox Code Playgroud)

这个看起来不错,但我想知道是否有更优雅,高效或功能性的方法来实现这一目标.也许隐藏在标准库中的一些甜蜜的东西...在此先感谢.

小智 7

如果您想在Python中使用函数式编程风格,您可能需要查看toolz包.有了toolz,你可以简单地做:

toolz.unique(obj_list, key=lambda x: x.my_attr)
Run Code Online (Sandbox Code Playgroud)

为了获得更好的性能,您可以使用operator.attrgetter('my_attr')lambda函数代替键.你也可以使用cytoolz,这是一个用Cythontoolz编写的快速实现.

  • 这恰好填补了我在python中缺少的FP差距.非常感谢你! (2认同)