2015-08-30 5 views
12

У меня есть список наборов:удаление дубликатов в списке наборов

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])] 

(на самом деле в моем случае преобразования списка взаимных кортежей)

, и я хочу, чтобы удалить дубликаты, чтобы получить :

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

Но если я стараюсь:

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

Или

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

Как получить список наборов с различными наборами?

+0

Одним из способов может быть преобразование списка 'set' в' list' из 'list', а затем удаление дубликатов, а затем преобразование элементов' list' обратно в 'set'. – ZdaR

+0

@ZdaR Я собираюсь сказать это жирным шрифтом: ** Ваш намек неверен **. Следуя части ваших инструкций, которые говорят: «* преобразуйте список' set' в 'list' из' list', а затем удалите «dupicates *», мы получаем этот список (map (list, [{3, 11}, {11, 3}])) 'output' [[3, 11], [11, 3]]'. – ogogmad

ответ

16

Лучший способ для преобразования наборов для frozenset с (которые hashable), а затем использовать set получить только уникальные наборы, как этот

>>> 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})] 

Если вы хотите их наборы, то вы можете конвертировать их обратно в set с так

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

Если вы хотите, чтобы заказ также будет поддерживаться, в то время как удаление дубликатов, то вы можете использовать collections.OrderedDict, как этот

>>> 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 Он существует в 2.7, поэтому утверждение не является строгим. –

+0

@DanD: Ой! Я изначально просто посмотрел на [Документы Python 3] (https://docs.python.org/3/library/collections.html#collections.OrderedDict), где он говорит «Новое в версии 3.1». Но я только что проверил в документах Python 2, и он говорит «Новое в версии 2.7.»; Я должен был проверить там, чтобы убедиться, что он был перенесен обратно. Извини за это. Я удалю мои комментарии. –

2

Альтернативой с использованием цикла:

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

Лучше использовать '[]' чем 'list()' для создания списка –

+0

Почему это Bhargav Rao? –

+1

@ReblochonMasque: это потому, что '[]' - это литеральный синтаксис (позволяющий создавать пустые списки во время компиляции), тогда как 'list()' является вызовом функции (имя функции должно быть просмотрено во время выполнения, а затем вызвано верните пустой список). Последнее немного дороже. –

1

Вот еще одна альтернатива

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

** Этот ответ неверен **. Два равных множества могут быть сопоставлены двум различным наборам. Я видел это. Например: 'ss = [{3, 11}, {11, 3}]; list (map (tuple, ss)) 'выходы' [(3, 11), (11, 3)] ' – ogogmad

0

Существует еще одна альтернатива.

import itertools 
list_sets = [set(['a', 'e', 'f']), set(['c', 'b', 'f']), set(['a', 'e', 'f']), set(['a', 'd']), set(['a', 'e', 'f'])] 

lists = [list(s) for s in list_sets] # convert a list of sets to a list of lists 
lists.sort() 
lists_remove_duplicates = [lists for lists,_ in itertools.groupby(lists)] 
print(lists_remove_duplicates) 

# output 
[['a', 'd'], ['a', 'e', 'f'], ['c', 'b', 'f']] 
Смежные вопросы