2015-03-03 165 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')] 

我怎樣才能在Python的實現這一目標辦法? 謝謝!

回答

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 2015-03-16 09:36:03

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)方法。 – 2015-03-03 14:23:02

+0

@MartijnPieters不幸的是!但也許它對於OP來說並不重要!我提到'set'是一個更好的配方! – Kasramvd 2015-03-03 14:24:41

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:道歉。使用的集合。 – 2015-03-03 14:53:19

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

我只是看到在寫這篇文章時發佈了類似的答案。抱歉! :) – 2015-03-03 14:29:14

+2

同樣的評論給你:使用一個列表來跟蹤獨特的元素是**慢**,因爲每個測試需要'len(lst_banned)'步驟。一套可以讓你測試*常數時間*的成員資格。 – 2015-03-03 14:29:42

+0

好點! 'set'更加pythonic ...我想,這也是問題的關鍵! – 2015-03-03 14:33:27