2013-12-20 3 views
4

Как удалить список объектов в Python, сохранить заказ?Как uniq список объектов?

def Test(object): 
    def __init__(self,p1,p2): 
     self.p1 = p1 
     self.p2 = p2 
lst = [Test(1,2), Test(2,3), Test(1,2)] 

Два объекта уник, если

Test1.p1 == Test2.p1 and Test1.p1 == Test2.p2 
+1

Определить уникальность? это 'p1' то же самое в обоих или' p2'? –

+0

@AamirAdnan на основе контекста Предполагаю, что ему нужен упорядоченный список, содержащий только уникальные элементы. – maxywb

+0

листинг как в виде наборов 'p1 = set (p1)' then 'p1 = p1.union (p2)' даст набор, содержащий все уникальные. затем отсортируйте его. [set] (http://docs.python.org/2/library/sets.html) –

ответ

-1

Вы могли бы сделать что-то, что чувствует себя Hacky, но он должен работать для вас:

tmpset = set(lst) 
uniqsorted = list(tmpset).sort() 
+1

Не работает, если исходный порядок не отсортирован. – Fenikso

+0

Нет, не будет. Но до того, как он редактировал вопрос о том, что именно он просил, было неясно. – maxywb

0

Использование collections.OrderedDict:

class Test(object): 
    def __init__(self, p1, p2): 
     self.p1 = p1 
     self.p2 = p2 

lst = [Test(1,2), Test(2,3), Test(1,2)] 


import collections 
d = collections.OrderedDict() 
for x in lst: 
    key = x.p1, x.p2 
    if key not in d: 
     d[key] = x 

for test_item in d.values(): 
    print(test_item.p1, test_item.p2) 

отпечатки

1 2 
2 3 
1

Я изменяю свой ответ, чтобы сохранить порядок. Вы можете определить только равенство (путем добавления __eq__ метода) и добавить ваши детали по одному в новый список, в то время как проверка, если они уже присутствуют:

class Test(object): 
    def __init__(self,p1,p2): 
     self.p1 = p1 
     self.p2 = p2 

    def __eq__(self, ot): 
     return self.p1 == ot.p1 and self.p2 == ot.p2 


lst = [Test(1,2), Test(2,3), Test(1,2)] 
new_lst = [] 
for x in lst: 
    if x not in new_lst: 
     new_lst.append(x) 
+1

Ждите, это не экономят порядок – GermanK

+1

Скопировано из [dublicate question answer] (http://stackoverflow.com/questions/4169252/remove-duplicates-in-list-of-object-with-python). – niekas

+0

Теперь он делает, и нет, я не копировал :) – GermanK

5
class Test(object): 
    def __init__(self,p1,p2): 
     self.p1 = p1 
     self.p2 = p2 

    def __eq__(self, other): 
     return (other.p1 == self.p1) and (other.p2 == self.p2) 

    def __hash__(self): 
     return (self.p1 << 64) | self.p2 

lst = [Test(1,2), Test(2,3), Test(1,2)] 
from collections import OrderedDict 
uniq = list(OrderedDict.fromkeys(lst, 0)) 
print [[item.p1, item.p2] for item in uniq] 
  1. Если мы используем объекты в hashable коллекциях, мы должны определить __hash__ и __eq__ функции.

  2. Я использовал (self.p1 << 64) | self.p2 как хэш, в предположении, что число p1 и p2 не будет превышать 2^64 (18446744073709551616).

  3. Это работает, но не делает этого. Класс, который вы создали, изменен, что означает, что состояние объекта может быть изменено (в основном вы будете менять p1 и p2). Если состояние объекта может измениться, значение хэша также изменится. Как вы видите, мы полагаемся на __hash__, чтобы сохранить объект в OrderedDict.

+0

Я просто подумал о том же решении и не был уверен, как построить хеш-значение. Изменение значения p1 может работать в зависимости от ожидаемых значений. – Matthias

+3

Я бы использовал 'hash ((self.p1, self.p2))' как значение хэш-функции. Если Тест был непреложным ... – RemcoGerlich

0

В качестве альтернативы, с генератором, который отслеживает ключи это уже видели, используя набор:

def unique_values(iterable): 
    seen = set() 
    for value in iterator: 
     key = (value.p1, value.p2) 
     if key not in seen: 
      yield value 
      seen.add(key) 

lst = list(unique_values(lst)) 
Смежные вопросы