【问题标题】:Python, remove duplicates from list of tuplesPython,从元组列表中删除重复项
【发布时间】:2011-06-29 08:59:51
【问题描述】:

我有以下清单:

[('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))]

【问题讨论】:

    标签: python list items


    【解决方案1】:

    您可以使用字典来存储迄今为止为给定键找到的最高值:

    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 作为变量名可能不是一个好主意。不过答案很好。
    • 这种情况你可以考虑collections.namedtuple来避免[2]
    【解决方案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's answer

    【讨论】:

    • +1 这个方法当然比我的要好,如果列表还是排序的话。
    【解决方案3】:
    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()]
    

    【讨论】:

      【解决方案4】:

      您可以通过对列表进行排序并通过 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))]
      

      【讨论】:

        【解决方案5】:

        给你。

        #!/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)
        

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-22
          • 2013-11-28
          • 2018-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多