2015-03-03 2 views
3

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

[(67, u'top-coldestcitiesinamerica'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (65, u'a-b-c-ca-d-ab-ea-d-c-c'), (64, u'a-b-c-ca-d-ab-ea-d-c-c'), (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (62, u'ghgemissions'), (61, u'top-coldestcitiesinamerica'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (57, u'culture'), (55, u'cas-k-ihaveanidea'), (54, u'trendsfor'), (53, u'batteryimpedance'), (52, u'evs-howey-full'), (51, u'bericht'), (49, u'classiccarinsurance'), (47, u'uploaded_file'), (46, u'x_file'), (45, u's-s-main'), (44, u'vehicle-propulsion'), (43, u'x_file')] 

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

(67, u'top-coldestcitiesinamerica') 
(61, u'top-coldestcitiesinamerica') 

..are дубликаты, и я хотел бы, чтобы удалить один из них (по аналогии с set). Так, в конце концов, я хотел бы иметь чистый список кортежей без каких-либо дубликатов, как так (т.е. без дубликатов на первый элемент кортежа):

[(67, u'top-coldestcitiesinamerica'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (65, u'a-b-c-ca-d-ab-ea-d-c-c') (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (62, u'ghgemissions'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (57, u'culture'), (55, u'cas-k-ihaveanidea'), (54, u'trendsfor'), (53, u'batteryimpedance'), (52, u'evs-howey-full'), (51, u'bericht'), (49, u'classiccarinsurance'), (47, u'uploaded_file'), (46, u'x_file'), (45, u's-s-main'), (44, u'vehicle-propulsion')] 

Как я могу добиться этого в питоновских путь? Спасибо!

ответ

5

Вы можете использовать set подход от How do you remove duplicates from a list in whilst preserving order?, используя x[1] в качестве уникального идентификатора:

def unique_second_element(seq): 
    seen = set() 
    seen_add = seen.add 
    return [x for x in seq if not (x[1] in seen or seen_add(x[1]))] 

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

Вы могли бы сделать это еще более общий характер, поддерживая key функцию:

def unique_preserve_order(seq, key=None): 
    if key is None: 
     key = lambda elem: elem 
    seen = set() 
    seen_add = seen.add 
    augmented = ((key(x), x) for x in seq) 
    return [x for k, x in augmented if not (k in seen or seen_add(k))] 

затем использовать

import operator 

unique_preserve_order(yourlist, key=operator.itemgetter(1)) 

Демо:

>>> def unique_preserve_order(seq, key=None): 
...  if key is None: 
...   key = lambda elem: elem 
...  seen = set() 
...  seen_add = seen.add 
...  augmented = ((key(x), x) for x in seq) 
...  return [x for k, x in augmented if not (k in seen or seen_add(k))] 
... 
>>> from pprint import pprint 
>>> import operator 
>>> yourlist = [(67, u'top-coldestcitiesinamerica'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (65, u'a-b-c-ca-d-ab-ea-d-c-c'), (64, u'a-b-c-ca-d-ab-ea-d-c-c'), (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (62, u'ghgemissions'), (61, u'top-coldestcitiesinamerica'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (57, u'culture'), (55, u'cas-k-ihaveanidea'), (54, u'trendsfor'), (53, u'batteryimpedance'), (52, u'evs-howey-full'), (51, u'bericht'), (49, u'classiccarinsurance'), (47, u'uploaded_file'), (46, u'x_file'), (45, u's-s-main'), (44, u'vehicle-propulsion'), (43, u'x_file')] 
>>> pprint(unique_preserve_order(yourlist, operator.itemgetter(1))) 
[(67, u'top-coldestcitiesinamerica'), 
(66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), 
(65, u'a-b-c-ca-d-ab-ea-d-c-c'), 
(63, 
    u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), 
(62, u'ghgemissions'), 
(58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), 
(57, u'culture'), 
(55, u'cas-k-ihaveanidea'), 
(54, u'trendsfor'), 
(53, u'batteryimpedance'), 
(52, u'evs-howey-full'), 
(51, u'bericht'), 
(49, u'classiccarinsurance'), 
(47, u'uploaded_file'), 
(46, u'x_file'), 
(45, u's-s-main'), 
(44, u'vehicle-propulsion')] 
+0

Извините, что задержка в ответе - я закончил использовать ваш метод 'unique_second_element' - работает как шарм. Большое спасибо! – AJW

1

В качестве альтернативного ответа вы можете использовать itertools.groupby() , это может быть полезно, если у вас есть огромный список, но не так хорошо, как set:

>>> from itertools import groupby 
>>> from operator import itemgetter 
>>> [next(g) for _,g in groupby(sorted(l,key=itemgetter(1)),itemgetter(1))] 
[(65, u'a-b-c-ca-d-ab-ea-d-c-c'), (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (53, u'batteryimpedance'), (51, u'bericht'), (55, u'cas-k-ihaveanidea'), (49, u'classiccarinsurance'), (57, u'culture'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (52, u'evs-howey-full'), (62, u'ghgemissions'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (45, u's-s-main'), (67, u'top-coldestcitiesinamerica'), (54, u'trendsfor'), (47, u'uploaded_file'), (44, u'vehicle-propulsion'), (46, u'x_file')] 
+0

Это убивает заказ, и сортировка делает это решением O (NlogN), по сравнению с моим подходом O (N). –

+0

@MartijnPieters К сожалению, да! но, возможно, это не вопрос для OP! и я упомянул, что 'set' - лучший рецепт! – Kasramvd

0
  1. Определение Проверьте список переменных, чтобы добавить ключ.
  2. Итерировать каждый элемент из списка ввода.
  3. Ключ-ключ находится в контрольном списке или нет.
  4. Если нет, то добавьте элемент в список результатов и список проверки обновлений.
  5. Распечатать результат.

код:

input_list = [(67, u'top-coldestcitiesinamerica'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (65, u'a-b-c-ca-d-ab-ea-d-c-c'), (64, u'a-b-c-ca-d-ab-ea-d-c-c'), (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (62, u'ghgemissions'), (61, u'top-coldestcitiesinamerica'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (57, u'culture'), (55, u'cas-k-ihaveanidea'), (54, u'trendsfor'), (53, u'batteryimpedance'), (52, u'evs-howey-full'), (51, u'bericht'), (49, u'classiccarinsurance'), (47, u'uploaded_file'), (46, u'x_file'), (45, u's-s-main'), (44, u'vehicle-propulsion'), (43, u'x_file')] 

check_list = set() 
result = [] 
for i in input_list: 
    if not i[1] in check_list: 
     result.append(i) 
     check_list.add(i[1]) 

import pprint 
pprint.pprint(result) 

Выход:

$ python task4.py 
[(67, u'top-coldestcitiesinamerica'), 
(66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), 
(65, u'a-b-c-ca-d-ab-ea-d-c-c'), 
(63, 
    u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), 
(62, u'ghgemissions'), 
(58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), 
(57, u'culture'), 
(55, u'cas-k-ihaveanidea'), 
(54, u'trendsfor'), 
(53, u'batteryimpedance'), 
(52, u'evs-howey-full'), 
(51, u'bericht'), 
(49, u'classiccarinsurance'), 
(47, u'uploaded_file'), 
(46, u'x_file'), 
(45, u's-s-main'), 
(44, u'vehicle-propulsion')] 
+0

@MartijnPieters: Апология. использован комплект. –

0

Я сделал это очень простой и легкий способ.

lst=[(67, u'top-coldestcitiesinamerica'), (66, u'ecofriendlyideastocelebrateindependenceday-phpapp'), (65, u'a-b-c-ca-d-ab-ea-d-c-c'), (64, u'a-b-c-ca-d-ab-ea-d-c-c'), (63, u'alexandre-meybeck-faowhatisclimate-smartagriculture-backgroundopportunitiesandchallenges'), (62, u'ghgemissions'), (61, u'top-coldestcitiesinamerica'), (58, u'infographicthe-stateofdigitaltransformationaltimetergroup'), (57, u'culture'), (55, u'cas-k-ihaveanidea'), (54, u'trendsfor'), (53, u'batteryimpedance'), (52, u'evs-howey-full'), (51, u'bericht'), (49, u'classiccarinsurance'), (47, u'uploaded_file'), (46, u'x_file'), (45, u's-s-main'), (44, u'vehicle-propulsion'), (43, u'x_file')] 

lst2 = [] #empty list to fill with unique tuples 
lst_banned = [] #empty list to fill with banned elements 

for tup in lst: 
    if tup[-1] not in lst_banned: 
     lst_banned.append(tup[-1]) 
     lst2.append(tup) 

lst=lst2 
del lst2 
del lst_banned 
+0

Я просто вижу, что был опубликован аналогичный ответ, когда я написал это. Сожалею! :) –

+2

Те же комментарии для вас: использование списка для отслеживания уникальных элементов ** медленно **, так как каждый тест принимает шаги len (lst_banned). Набор позволяет тестировать членство в * постоянном времени *. –

+0

Хороший вопрос! «set» больше pythonic ... Я думаю, в этом и был смысл вопроса! –

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