Python,从元组列表中删除重复项

4
我有以下列表:
[('mail', 167, datetime.datetime(2010, 9, 29)) , 
 ('name', 1317, datetime.datetime(2011, 12, 12)), 
 ('mail', 1045, datetime.datetime(2010, 8, 13)), 
 ('name', 3, datetime.datetime(2011, 11, 3))]

我希望能够删除列表中具有相同第一个元组项的项目,其中日期不是最新的。换句话说,我需要得到这个:

[('mail', 167, datetime.datetime(2010, 9, 29)) , 
 ('name', 1317, datetime.datetime(2011, 12, 12))]
5个回答

16

你可以使用字典来存储到目前为止找到的给定键的最高值:

temp = {}
for key, number, date in input_list:
    if key not in temp: # we see this key for the first time
        temp[key] = (key, number, date)
    else:
        if temp[key][2] < date: # the new date is larger than the old one
            temp[key] = (key, number, date)
result = temp.values()

使用“list”作为变量名可能不是一个好主意。尽管如此,答案仍然很好。 - Shawn Chin
1
这是一个情况,你可以考虑使用 collections.namedtuple 来避免 [2] - Neil G

2
以下方法使用字典来覆盖具有相同键的条目。由于列表按日期排序,因此较旧的条目将被更新为较新的条目。
temp = {}
for v in sorted(L, key=lambda L: L[2]): # where L is your list
    temp[v[0]] = v
result = temp.values()

或者,若想要更加简洁(但难以阅读)的代码:
result = dict((v[0],v) for v in sorted(L, key=lambda L: L[2])).values()

更新

如果列表已经(或大部分)按日期排序,则此方法应该相当快。如果没有,特别是如果它是一个大列表,那么这可能不是最好的方法。

对于未排序的列表,首先按关键字,然后再按日期排序,您可能会获得一些性能改进。例如:sorted(L, key=lambda L: (L[0],L[2]))

或者更好的方法是采用 Space_C0wb0y的答案


+1 如果列表已经排序,那么这种方法当然比我的更优。 - Björn Pollex

0
d = {}

for item in list:
    if (item[0], item[1]) not in d:
        d[(item[0], item[1])] = item[2]
    else:
        if item[2] > d[(item[0], item[1])]:
            d[(item[0], item[1])] = item[2]

item = [(x[0], x[1], d[x] for x in d.keys()]

0

你可以通过对列表进行排序并获取d[2]的最高值来实现:

    In [26]: d
    Out[26]: 
    [('mail', 167, datetime.datetime(2010, 9, 29, 0, 0)),
     ('name', 1317, datetime.datetime(2011, 12, 12, 0, 0)),
     ('mail', 1045, datetime.datetime(2010, 8, 13, 0, 0)),
     ('name', 3, datetime.datetime(2011, 11, 3, 0, 0))]

    In [27]: d.sort(key = lambda i: i[2], reverse=True)

    In [28]: d
    Out[28]: 
    [('name', 1317, datetime.datetime(2011, 12, 12, 0, 0)),
     ('name', 3, datetime.datetime(2011, 11, 3, 0, 0)),
     ('mail', 167, datetime.datetime(2010, 9, 29, 0, 0)),
     ('mail', 1045, datetime.datetime(2010, 8, 13, 0, 0))]

    In [29]: [i for pos, i in enumerate(d) if i[0] in [j[0] for j in d[pos+1:]]]
    Out[29]: 
    [('name', 1317, datetime.datetime(2011, 12, 12, 0, 0)),
     ('mail', 167, datetime.datetime(2010, 9, 29, 0, 0))]

-1

请拿好。

#!/usr/bin/python2

from pprint import pprint
import datetime

ol = [('mail', 167, datetime.datetime(2010, 9, 29)) , 
     ('name', 1317, datetime.datetime(2011, 12, 12)), 
     ('mail', 1045, datetime.datetime(2010, 8, 13)), 
     ('name', 3, datetime.datetime(2011, 11, 3))]

d = {}

for t in sorted(ol, key=lambda t: (t[0], t[2])):
    d[t[0]] = t
out = d.values()

pprint(out)

这将使用第一个和第三个元组元素作为键对列表进行排序,然后通过使用哈希表来删除重复项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接