首页 > 解决方案 > Python: filter objects in a list which has unique id values

问题描述

I have a list of objects in Python, like:

my_list = [
    SomeObject(id="hello", name="world"),
    SomeObject(id="hello", name="world"),
    SomeObject(id="foo", name="bar"),
]

Now I want a new list which only contains the object which has unique id values, so the expected list will be:

expected_list = [
    SomeObject(id="hello", name="world"),
    SomeObject(id="foo", name="bar"),
]

Is there a method in Python which can perform such a list filtering?


Update:

What I finally do is, create two lists, unique_id_list = [], and unique_object_list = []. for-loop: If object.id not in unique_id_list, append the id into unique_id_list, item in unique_object_list. Otherwise do nothing. Please also refer to the "most correct way" to do it properly (the voted answer).

标签: pythonlistfiltering

解决方案


最简洁的方法是,如果您能够SomeObject自己定义类,则通过定义SomeObject独特之处并指定__eq__,__ne____hash__允许唯一性比较的方法。__str__只是添加,以便我们可以用值打印它而不是打印,例如<__main__.SomeObject object at 0x10b2dedf0>

class SomeObject:

    def __init__(self, id, name):
        self.id = id
        self.name = name

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.id == other.id

    def __ne__(self, other):
        return not self == other

    def __hash__(self):
        return hash(self.id)
    
    def __str__(self):
        return "<SomeObject id={} name={}>".format(self.id, self.name)

然后您可以 apply set,从而过滤掉重复的对象,并将其转换回列表:

my_list = [
    SomeObject(id="hello", name="world"),
    SomeObject(id="hello", name="world"),
    SomeObject(id="foo", name="bar"),
]

filtered = list(set(my_list))

# print all objects in the list:
[print(o) for o in filtered]

将打印出过滤列表中的项目:

<SomeObject id=hello name=world>
<SomeObject id=foo name=bar>

推荐阅读