2016-07-10 17 views
1

我創建了一個包含字符串/數字屬性和列表屬性的Python類。現在我需要這個類的一些對象沒有重複的列表。這些對象可以具有相同的值(相等),但是不應該存在多於一次的對象。不重複的可變對象的Python列表

我知道集只支持不可變的對象,但我的對象的值將改變。

這個問題還有其他合適的數據類型嗎?從技術上講,我需要一個沒有實現所有集合類方法的重複對象引用數組。

+0

概念上,這不會使大量的意義,如果你改變了可變對象之一,你可能會改變它變成與其他列表中的東西。如果你正在進行一次性過濾,你可能會考慮採用「絞逼」的方法,將所有東西都轉換爲不可變類型,使用set()方法,然後轉換回可變類型。 –

+0

我並不在乎平等。這些對象代表了現實世界中的一個對象。對象可以是僅具有高度屬性的類「person」。列表中可以有多個同一高度的人,但每個人只能在那裏一次。 – schoeberl

+0

作爲鏈接問題的答案,建議使用自定義類進行設置,因爲默認的__hash__函數會返回基於對象標識的值,如果對象值發生更改,該標識不會更改。 – schoeberl

回答

0

set()完全按照您的希望工作。只需直接使用它:

class Person(object): 
    def __init__(self, height): 
     self.height = height 

Tom = Person(190) 
George = Person(200) 
Bob = Person(200) 

friends = set([Tom, George, Bob]) 
assert len(friends) == 3 
+0

我想知道他們爲什麼讓列表「不可干擾」,而它可以像自定義類一樣工作。如果Person是從列表派生的,我想這個解決方案將不起作用。 – schoeberl

0

我會建議一個for循環像這樣:

unique = [] 
for item in yourList: 
    if not item in unique: 
     unique.append(item) 

至於內置的類型,設置和你剛纔提到的類型的字典無法散列這些類。

0

如果我正確理解你的問題,你有一個可變類和一個相等運算符,檢查它的一些可變屬性以確定兩個實例是否相等。您希望構建這些實例的列表,不包括對同一實例的重複引用,而不是等值實例。

# given some pre-existing list of objects, initial_list 

seen_ids = set() 
deduped_list = [] 
for instance in initial_list: 
    if id(instance) not in seen_ids: 
     deduped_list.append(instance) 
     seen_ids.add(id(instance)) 

可以代替使用字典和發電機表達,如果你想要做的一切:

您可以通過保持id S中的值,到目前爲止,你已經包含的set做到這一點在一個表達式:如果你使用Python 3,需要一個實際的列表對象

deduped_list = list(dict((id(instance), instance) for instance in initial_list).values()) 

list通話纔是必需的。如果你只需要迭代一些東西,values的返回值就可以正常工作。如果您需要的值與第一次出現在原始列表中的順序相同,則可以使用OrderedDict

+0

我想這是一個解決方案,但用python管理內存地址(id()的返回值)似乎不是一個非常好的方法。 – schoeberl