【问题标题】:Count duplicates between 2 lists计算 2 个列表之间的重复项
【发布时间】:2011-06-14 02:02:08
【问题描述】:
a = [1, 2, 9, 5, 1]
b = [9, 8, 7, 6, 5]

我想计算两个列表之间的重复次数。因此,使用上述方法,我想返回 2 的计数,因为 9 和 5 对两个列表都是通用的。

我尝试了类似的方法,但效果不佳。

def filter_(x, y):
    count = 0
    for num in y:
        if num in x:
            count += 1
            return count

【问题讨论】:

  • 请注意,一旦它起作用(将return 删除两次),它就会具有O(n * m) 复杂性,即扩展得非常可怕。
  • @delnan 感谢您的提示。所以使用交叉点可以更好地扩展。
  • 是的。您实际上可以做得更好,但这需要不止一行代码(想法是您只需要一组第一个列表,然后迭代第二个并保留集合中的项目 - 节省创建第二个设置)。
  • a 包含两次1,如果b 还包含1,那么计数应该增加1 还是2

标签: python list loops


【解决方案1】:

你可以使用set.intersection:

>>> set(a).intersection(set(b)) # or just: set(a).intersection(b)
set([9, 5])

或者,对于交叉点的长度:

>>> len(set(a).intersection(set(b)))
2

或者,更简洁:

>>> len(set(a) & set(b))
2

【讨论】:

  • 我不想要 9,5。我要数 2。
  • 不需要显式地从列表b中创建一个集合,集合交集方法支持列表作为输入。
【解决方案2】:

将它们转换为sets 并计算交叉点。

 len(set(a).intersection(set(b)))

【讨论】:

    【解决方案3】:

    更短更好:

    >>> a = [1, 2, 9, 5, 1]
    >>> b = [9, 8, 7, 6, 5]
    >>> len(set(a) & set(b))     # & is intersection - elements common to both
    2 
    

    为什么您的代码不起作用:

    >>> def filter_(x, y):
    ...     count = 0
    ...     for num in y:
    ...             if num in x:
    ...                     count += 1
    ...     return count
    ... 
    >>> filter_(a, b)
    2
    

    您的 return count 在 for 循环中,它在执行未完成的情况下返回。

    【讨论】:

      【解决方案4】:

      如果您希望计算多个条目,则基于集合的解决方案将失败;你需要类似的东西

      from collections import Counter
      
      def numDups(a, b):
          if len(a)>len(b):
              a,b = b,a
      
          a_count = Counter(a)
          b_count = Counter(b)
      
          return sum(min(b_count[ak], av) for ak,av in a_count.iteritems())
      

      然后

      numDups([1,1,2,3], [1,1,1,1,1])
      

      返回 2。运行时间为 O(n+m)。

      还有,你的初始解决方案

      for num in y:
          if num in x:
              count += 1
      

      错误 - 应用于 [1,2,3,3] 和 [1,1,1,1,1,3],您的代码将返回 3 或 6,两者都不这是正确的(答案应该是 2)。

      【讨论】:

      • 这个解决方案更好,因为它也计算重复项,谢谢:)
      【解决方案5】:

      以下解决方案还考虑了列表中的重复元素:

      from collections import Counter
      
      def number_of_duplicates(list_a, list_b):
          count_a = Counter(list_a)
          count_b = Counter(list_b)
      
          common_keys = set(count_a.keys()).intersection(count_b.keys())
          return sum(min(count_a[key], count_b[key]) for key in common_keys)
      

      然后number_of_duplicates([1, 2, 2, 2, 3], [1, 2, 2, 4]) 会产生预期的3


      请注意,@Hugh Bothwell 也提供了类似的解决方案,但如果元素仅包含在较短的列表中,它有时会抛出 KeyError

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-06
        • 2014-04-27
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-21
        • 1970-01-01
        相关资源
        最近更新 更多