2015-08-30 30 views
12

Ich habe eine Liste der Sets:Entfernen Duplikate aus einer Liste von Sätzen

L = [set([1, 4]), set([1, 4]), set([1, 2]), set([1, 2]), set([2, 4]), set([2, 4]), set([5, 6]), set([5, 6]), set([3, 6]), set([3, 6]), set([3, 5]), set([3, 5])] 

(eigentlich in meinem Fall eine Umwandlung einer Liste von reziproker Tupel)

und ich mag um Duplikate entfernen zu bekommen :

L = [set([1, 4]), set([1, 2]), set([2, 4]), set([5, 6]), set([3, 6]), set([3, 5])] 

Aber wenn ich versuche:

>>> list(set(L)) 
TypeError: unhashable type: 'set' 

Oder

>>> list(np.unique(L)) 
TypeError: cannot compare sets using cmp() 

Wie erhalte ich eine Liste von Sets mit verschiedenen Sätzen?

+0

Ein Weg könnte sein, die Liste von 'set' in' list' von 'list' umzuwandeln und dann die Duplikate zu entfernen und dann die' list' Elemente zurück in 'set' zu konvertieren. – ZdaR

+0

@ZdaR Ich werde das in Fettschrift sagen: ** Dein Tipp ist falsch. ** Befolge den Teil deiner Instruktionen, der sagt "* konvertiere die Liste von' set' in 'liste' von' list' und entferne dann die duplicates * ", wir bekommen diese' liste (map (liste, [{3, 11}, {11, 3}])) "outputs" [[3, 11], [11, 3]] '. – ogogmad

Antwort

16

Der beste Weg ist Ihre Sets frozenset s zu konvertieren (die hashable sind) und dann set verwendet nur die eindeutigen Sätze zu bekommen, wie diese

>>> list(set(frozenset(item) for item in L)) 
[frozenset({2, 4}), 
frozenset({3, 6}), 
frozenset({1, 2}), 
frozenset({5, 6}), 
frozenset({1, 4}), 
frozenset({3, 5})] 

Wenn Sie sie als Sätze wollen, dann können Sie konvertieren sie wie folgt

>>> [set(item) for item in set(frozenset(item) for item in L)] 
[{2, 4}, {3, 6}, {1, 2}, {5, 6}, {1, 4}, {3, 5}] 

zu set s zurück Wenn Sie das wollen, um auch beibehalten werden, während die Duplikate zu entfernen, dann können Sie verwenden collections.OrderedDict, wie diese

>>> from collections import OrderedDict 
>>> [set(i) for i in OrderedDict.fromkeys(frozenset(item) for item in L)] 
[{1, 4}, {1, 2}, {2, 4}, {5, 6}, {3, 6}, {3, 5}] 
+0

@ PM2Ring Es existiert in 2.7, so dass die Aussage nicht streng wahr ist. –

+0

@DanD: Ups! Ich habe ursprünglich nur die [Python 3 Dokumente] (https://docs.python.org/3/library/collections.html#collections.OrderedDict) angeschaut, wo es heißt "Neu in Version 3.1". Aber ich habe gerade die Python-2-Dokumente eingecheckt und es heißt "Neu in Version 2.7."; Ich hätte nachsehen sollen, ob es zurückportiert wurde. Das tut mir leid. Ich werde meine Kommentare entfernen. –

2

Eine Alternative mit einer Schleife:

result = list() 
for item in L: 
    if item not in result: 
     result.append(item) 
+1

Es ist besser, '[]' als 'list()' zu verwenden, um eine Liste zu erstellen –

+0

Warum ist das Bhargav Rao? –

+1

@ReblochonMasque: Es ist, weil '[]' ist literal Syntax (ermöglicht die leere Liste instanziiert werden, während der Kompilierung) während 'list()' ist ein Funktionsaufruf (der Funktionsname muss zur Laufzeit nachgeschlagen und dann aufgerufen werden die leere Liste zurückgeben). Letzteres ist etwas teurer. –

1

Hier ist eine weitere Alternative

yourNewSet = map(set,list(set(map(tuple,yourSet)))) 
+0

** Diese Antwort ist falsch **. Zwei gleiche Sätze können auf zwei verschiedene Tupel abgebildet werden. Ich habe gesehen, dass das passiert ist. Zum Beispiel: 'ss = [{3, 11}, {11, 3}]; list (map (tuple, ss)) 'outputs' [(3, 11), (11, 3)] ' – ogogmad

Verwandte Themen