我有一個 MyClass 物件串列,它是這樣制作的:
# The class is MyClass(string_a: str = None, string_b: str = None)
test_list: List[MyClass] = []
test_clist.append(MyClass("hello", "world"))
test_clist.append(MyClass("hello", ""))
test_clist.append(MyClass("hello", "world"))
test_clist.append(MyClass(None, "world")
我希望最終結果只洗掉第三個附加:
# Remove test_clist.append(MyClass("hello", "world"))
這只是一個示例,物件串列在串列或 n 中可以沒有任何內容。有沒有辦法快速洗掉它們或更好的方法,比如如何在追加之前快速判斷它是否已經存在?
uj5u.com熱心網友回復:
如果您的物件是原始型別,則可以使用 set
list(set(test_clist))
如果沒有,就像您的情況一樣,那么您有 2 個解決方案
1- 實施__hash__()&__eq__()
您必須在類中實作__hash__()&__eq__才能set()用于洗掉重復項
見下面的例子
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"MyClass({self.x} - {self.y})"
def __hash__(self):
return hash((self.x, self.y))
def __eq__(self, other):
if self.__class__ != other.__class__:
return NotImplemented
return (
self.x == other.x and
self.y == other.y
)
l = []
l.append(MyClass('hello', 'world'))
l.append(MyClass('hello', 'world'))
l.append(MyClass('', 'world'))
l.append(MyClass(None, 'world'))
print(list(set(l)))
由于您有多個要用于比較__hash__()的鍵,因此使用鍵元組。
__repr__() 僅用于將類的物件表示為字串。
2- 使用第 3 方套餐
查看一個名為toolz的包
然后使用unique()方法通過傳遞密鑰來洗掉重復項
toolz.unique(test_list, key=lambda x: x.your_attribute)
在您的情況下,您有多個屬性,因此您可以將它們合并為一個,例如通過為它們創建一個連接屬性然后將其toolz.unique()作為您的鍵傳遞,或者像下面那樣將它們即時連接
toolz.unique(test_list, key=lambda x: x.first_attribute x.second_attribute)
uj5u.com熱心網友回復:
您可以使用set從串列中洗掉重復項,但是當您使用自己的類物件時,這對您來說開箱即用。要使set作業,您需要實作*__eq__*dunder 方法,該方法使您能夠根據物件存盤的值比較類物件。一個簡單的例子是:
def __eq__(self, obj, *args, **kwargs):
return isinstance(obj, MyClass) and obj.first_name == self.first_name and ..
一旦你的班級有了這個,你就可以使用 set(test_list) 洗掉重復項。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/351696.html
標籤:Python 列表 python-3.7
上一篇:如何讓輸出向后列印?[復制]
