【问题标题】:Removing the lists from a list which are duplicated for some items从列表中删除某些项目重复的列表
【发布时间】:2013-05-28 12:02:04
【问题描述】:

我正在尝试从具有相同第一项和第三项但仅保留第一项的列表中删除列表。示例列表和输出:

li=[ [2,4,5], [1,3,5], [1,6,5] ]
output_list = [ [2,4,5], [1,3,5] ]

我编写的代码需要很长时间才能执行,因为原始列表包含数百万个列表。

b_li = []
output_list = []
for x in li:
    s = [ x[0], x[2] ]
    if s not in b_li:
        b_li.append(s)
        output_list.append(x)

如何改进代码?提前致谢。

【问题讨论】:

  • 使用集合而不是列表来记录看到的第一对/最后一对。
  • 根据您的使用情况,您可以返回一个迭代器而不是创建一个新列表。它将为您节省大量内存。

标签: python list


【解决方案1】:

使用集合来存储所见元素。那更快:

seen = set()
res = []
for entry in li:
    cond = (entry[0], entry[2])
    if cond not in seen:
        res.append(entry)
        seen.add(cond)


[[2, 4, 5], [1, 3, 5]]

添加

此外,花在考虑告诉变量名称上的时间通常是值得的。通常情况下,最初被认为是一次性解决方案的时间比预期的要长得多。

【讨论】:

  • 谢谢,这是一个巨大的飞跃 :)
【解决方案2】:

利用OrderedDict 和字典具有唯一键的事实。

>>> from collections import OrderedDict
>>> li=[ [2,4,5], [1,3,5], [1,6,5] ]
>>> OrderedDict(((x[0], x[2]), x) for x in reversed(li)).values()
[[1, 3, 5], [2, 4, 5]]

【讨论】:

    【解决方案3】:

    这是一个基于@iurisilvio 的迭代器注释的解决方案,它使用itertools.compress 和其他基于set 的解决方案。 不是从输入列表中的元素构建output_list,而是根据输入列表中的元素在一对一的基础上构建包含布尔值的selector 列表。 True 的值表示输入列表中的相应元素应保留在输出中。然后可以通过itertools.compress 将selector 应用于输入列表以生成可迭代的输出。

    from itertools import compress
    li=[ [2,4,5], [1,3,5], [1,6,5] ]
    b_li = set()
    selectors = []
    for x in li:
        s = (x[0], x[2])
        if s not in b_li:
            b_li.add(s)
            selectors.append(True)
        else:
            selectors.append(False)
    
    for x in compress(li, selectors):
      print x
    [2, 4, 5]
    [1, 3, 5]
    

    【讨论】:

      【解决方案4】:

      改进版:

      b_li = set()
      output_list = []
      b_li_add = b_li.add
      output_list_append = output_list.append
      for x in li:
          s = (x[0], x[2])
          if s not in b_li:
              b_li_add(s)
              output_list_append(x)
      

      变化如下:

      • 为b_li 使用set(),这样可以加快查找速度。
      • 将s 转换为元组,因为不需要将唯一的第一个和第三个元素存储为列表。
      • 减少的函数查找也加快了代码速度。

      【讨论】:

        猜你喜欢
        • 2011-07-23
        • 2011-10-07
        • 2021-12-08
        • 2016-06-24
        • 2011-01-13
        • 2011-09-29
        相关资源
        最近更新 更多