2014-12-21 2 views
-1

Мои данные выглядят следующим образом:Удаление дубликатов (не с помощью набора)

let = ['a', 'b', 'a', 'c', 'a'] 

Как удалить дубликаты? Я хочу, чтобы мой выход будет что-то вроде этого:

['b', 'c'] 

Когда я использую функцию set, я получаю:

set(['a', 'c', 'b']) 

Это не то, что я хочу.

+0

Для какого языка ? (Измените свой вопрос и добавьте его в теги) –

+0

@michnguyen Вам нужно будет немного разъяснить, что вы пытаетесь выполнить, потому что это не просто удаление дубликатов (если это так, то «а» будет включены в результат). – rchang

ответ

2

Один из вариантов (как производное от ответа Ritesh Кумар here)

let = ['a', 'b', 'a', 'c', 'a'] 
onlySingles = [x for x in let if let.count(x) < 2] 

, который дает

>>> onlySingles 
['b', 'c'] 
+0

Это довольно тяжелый пробег 'let.count' каждый раз –

+0

например: это делает линейное сканирование' let' в 25 раз. Либо сортировать/группировать, либо делать линейное частотное число * один раз *, что может уменьшить пространство ключа, а затем перебрать этот ... худший случай для более позднего - 2N –

1

Попробуйте это,

>>> let 
['a', 'b', 'a', 'c', 'a'] 
>>> dict.fromkeys(let).keys() 
['a', 'c', 'b'] 
>>> 
+0

Wow! Я не думал об этом ... –

+0

Это в основном использование маскировки. – 9000

0

Сортировка ввода, а затем удаление дубликатов становится тривиальным:

data = ['a', 'b', 'a', 'c', 'a'] 

def uniq(data): 
    last = None 
    result = [] 
    for item in data: 
    if item != last: 
     result.append(item) 
     last = item 
    return result 

print uniq(sorted(data)) 
# prints ['a', 'b', 'c'] 

Это, в основном, идиома корпуса cat data | sort | uniq. Стоимость O (N * log N), такая же, как и на основе дерева.

0

Вместо сортировки или линейного сканирования и повторного подсчета основного списка для его появления каждый раз.

Подсчитать количество вхождений, а затем фильтровать элементы, которые появляются один раз ...

>>> from collections import Counter 
>>> let = ['a', 'b', 'a', 'c', 'a'] 
>>> [k for k, v in Counter(let).items() if v == 1] 
['c', 'b'] 

Вы есть посмотреть на последовательность, по крайней мере один раз, независимо - хотя это имеет смысл ограничить количество когда вы это делаете.

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

>>> from itertools import groupby, islice 
>>> [k for k,v in groupby(sorted(let)) if len(list(islice(v, 2))) == 1] 
['b', 'c']