2016-01-03 2 views
7

У меня есть список, который выглядит следующим образом:Keep, во-первых обнаружил повторяющиеся элементы в списке

[(1, 0.3), (3, 0.2), (3, 0.15), (1, 0.07), (1, 0.02), (2, 0.01)] 

Я хочу держать во-первых, нашли повторяющиеся элементы в этом списке, на основе первого элемента в каждом наборе:

[(1, 0.3), (3, 0.2), (2, 0.01)] 

Есть ли эффективный способ сделать это?

ответ

4

Если вы используете функцию генератора вы ч п лениво возвращать первые простофили, все, что вам нужно хранить ключи, которые будут gc'd раз функции заканчивается:

def first_found(l): 
    seen = set() 
    for k, v in l: 
     if k not in seen: 
      yield (k, v) 
     seen.add(k) 

Какой для вашего списка даст вам:

print(list(first_found(l))) 
[(1, 0.3), (3, 0.2), (2, 0.01)] 

Или обновить первоначальный список:

l[:] = first_found(l) 

Или создать Dict:

od = OrderedDict(first_found(l)) 

print(od) 
OrderedDict([(1, 0.3), (3, 0.2), (2, 0.01)]) 
+1

Действительно приятное решение! – jbg

+0

@ JasperBryant-Greene, спасибо. –

7

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

>>> items = [(1, 0.3), (3, 0.2), (3, 0.15), (1, 0.07), (1, 0.02), (2, 0.01)] 
>>> list(dict(reversed(items)).items()) 
[(1, 0.3), (2, 0.01), (3, 0.2)] 

Если порядок результирующих вопросов списка см ответа Padraic в :)

+0

Это не будет поддерживать первоначальный порядок элементов. Кроме того, он будет работать нормально. – thefourtheye

+0

Хорошая точка Padraic. Я обновил ответ, чтобы использовать 'reverseed()'. На Python 3 больше не будет копий с этим решением, чем при использовании цикла for. На Python 2, если 'items()' заменяется на 'iteritems()', то копий больше не будет, чем при использовании цикла for. – jbg

+0

Хорошая точка - учитывая, что это все равно скопирует список, я вернул пример «LastUpdatedOrderedDict», чтобы просто использовать '[:: - 1]', чтобы отменить список. – jbg

Смежные вопросы