簡體   English   中英

Python:過濾列表中具有唯一 id 值的對象

[英]Python: filter objects in a list which has unique id values

我在 Python 中有一個對象列表,例如:

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

現在我想要一個僅包含具有唯一id值的 object 的新列表,因此預期的列表將是:

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

Python 中是否有可以執行此類列表過濾的方法?


更新:

我最后要做的是,創建兩個列表, unique_id_list = []unique_object_list = [] for-loop:如果object.id不在unique_id_list中,append 將 id 放入unique_id_list中,item 在unique_object_list中。 否則什么都不做。 另請參閱“最正確的方法”以正確執行(投票答案)。

最簡潔的方法是,如果您能夠自己定義SomeObject class,則通過定義使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)

然后您可以應用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>

將 id 添加到集合中,然后刪除不唯一的列表成員:

def some_object(id="bar", name="baz"):
    return id, name


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

print(my_list)
ids = set()
for obj in my_list:
    if (id := obj[0]) in ids:
        del my_list[my_list.index(obj)]
    ids.add(obj[0])

print(my_list)

返回:

[('hello', 'world'), ('hello', 'world'), ('foo', 'bar')]
[('hello', 'world'), ('foo', 'bar')]

遍歷 my_list 中的每個元素,檢查 expected_list 中的所有元素:如果它們中的任何一個匹配 id,則不要將其添加到列表中。

def delete_duplicates(total_list):
    expected_list = []
    in_expected_list = False
    for i in total_list:
        for j in expected_list:
            if j.id == i.id:
                in_expected_list = True
        if not in_expected_list:
            expected_list.append(i)
        in_expected_list = False

    return expected_list

您可以使用itertools.groupby ,如下所示:

class SomeObject:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)


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

from itertools import groupby

sort_function = lambda obj: obj.id
my_list = [list(item)[0] 
           for key, item in groupby(sorted(my_list, key=sort_function), key=sort_function)]
print(my_list)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM