【问题标题】:Remove partially duplicate tuples from list of tuples从元组列表中删除部分重复的元组
【发布时间】:2019-01-23 23:50:15
【问题描述】:

我有一个元组列表,如果它的第一项与列表中其他元组的第一项匹配,则需要删除元组。第三项可能相同也可能不同,所以我不能使用 set(我已经看到这个问题 - Grab unique tuples in python list, irrespective of order 这与我的问题不同)

例如,如果我得到 a 为:

[(0, 13, 'order1'), (14, 27, 'order2'), (14, 27, 'order2.1'), 
 (0, 13, 'order1'), (28, 41, 'order3')]

我希望输出为:

[(14, 27, 'order2'), (0, 13, 'order1'), (28, 41, 'order3')]

我正在使用以下代码获得所需的输出。

for e, i in enumerate(a):
    r = [True if i[0] == k[0] and e != j else False for j, k in enumerate(a)]
    if any(r):
        a.pop(e)
pprint(a)

有没有更好或更pythonic的方法来实现相同的目标?

【问题讨论】:

  • 如果你找到两个重复项,比如`(14, 27, 'order2')` 和(14, 27, 'order2.1'),你怎么知道要使用哪个第三项,'order2''order2.1'
  • 元组中的第二项无关紧要?
  • @JoePatten 无所谓,我可以随便选一个
  • 在迭代列表时 更改列表通常是一个糟糕 的想法。
  • @prune 不是真的(如果我同意,解决方案会有所不同吗?)并且我同意/知道这是更改列表的一个最糟糕的想法,因此这篇文章,寻找“更好/更pythonic”的解决方案。

标签: python


【解决方案1】:

通常的方法是使用 dict 关闭您想要重复数据删除的任何内容,例如:

>>> a = [(0, 13, 'order1'), (14, 27, 'order2'), (14, 27, 'order2.1'), (0, 13, 'order1'), (28, 41, 'order3')] 
>>> print(*{tup[:2]: tup for tup in a}.values()) 
(0, 13, 'order1') (14, 27, 'order2.1') (28, 41, 'order3')

这是 O(n) 时间复杂度,优于 O(n log n) 基于 groupby 的方法。

【讨论】:

    【解决方案2】:

    您应该避免在迭代列表时就地修改列表。相反,您可以使用流行的itertools unique_everseen recipe,也可以在第 3 方more_itertools 中使用。只需在 key 参数中使用 operator.itemgetter

    from more_itertools import unique_everseen
    from operator import itemgetter
    
    res = list(unique_everseen(L, key=itemgetter(0, 1)))
    

    此解决方案需要 O(n) 时间,但通常比基于字典的解决方案效率低,尽管它的意图可以说是更清晰。

    【讨论】:

      【解决方案3】:

      您可以在分组的排序列表中获取每个组的第一个元素:

      from itertools import groupby
      from operator import itemgetter
      
      a = [(0, 13, 'order1'), (14, 27, 'order2'), (14, 27, 'order2.1'), (0, 13, 'order1'), (28, 41, 'order3')]
      
      result = [list(g)[0] for k, g in groupby(sorted(a), key=itemgetter(0))]
      print(result)
      

      【讨论】:

        猜你喜欢
        • 2018-12-25
        • 2018-10-17
        • 1970-01-01
        • 2019-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-01
        相关资源
        最近更新 更多