Counter在python集合包中使用的算法?

时间:2016-11-28 10:18:35

标签: python algorithm

我想检查另一组单词中是否存在一组单词,例如

list1=['Hello','World']
list2=['Hello','World','Good','Bye']

我编写了以下代码来检查list1中存在的单词是否也出现在list2

def check(list1,list2):
 for l in list1:
  if l not in list2:
   return False
 return True

但是这个代码对于大输入失败了。然后我发现net中的以下代码适用于所有输入

from collections import Counter
def check(list1,list2):
 return not (Counter(list1) - Counter(list2))

任何人都可以告诉我计数器使用什么算法或提供任何其他方法,使用哪种方法可以在不使用内置函数的情况下实现相同的结果。

2 个答案:

答案 0 :(得分:2)

Counter的源代码将Counter定义为bag或multiset。 计数过程采用update方法,并且不包含任何特殊内容 - 它只是迭代所有元素并计算它们的出现次数。

在你的情况下,set就足够了:

def check(list1, list2):
    # all items from list1 in list2
    return set(list1) <= set(list2)

如果您也不能使用set,我建议您:

  1. 对两个列表进行排序
  2. 遍历list1(item1)的不同项目
  3. 迭代list2的项目,直到你富有item1或list2的结尾,这意味着item不在list2中,结束list1循环。
  4. 我会花费2nlogn + 2n时间。

    def check(list1, list2):
        j = 0
        prev = None
        for item1 in list1:
            if prev is not None and item1 == prev:
                continue
    
            while j < len(list2):
                if list2[j] == item1:
                    break
                if list2[j] > item1:
                    return False
                j += 1
            else:
                return False
    
            prev = item1
            j += 1
    
        return True
    

答案 1 :(得分:2)

Python 2.7.12 转到你的python安装,在Lib文件夹中你会找到一个名为 collections.py 的文件

第555-563行之间的所有内容都是用于填充单词字典及其相应计数的算法。基本上,Counter(list1)的输出是一个字典,其中单词为键,计为值。

允许你减去的东西存在于同一个文件中 - 第652-669行(粘贴在下面)

def __sub__(self, other):
        ''' Subtract count, but keep only results with positive counts.

        >>> Counter('abbbc') - Counter('bccd')
        Counter({'b': 2, 'a': 1})

        '''
        if not isinstance(other, Counter):
            return NotImplemented
        result = Counter()
        for elem, count in self.items():
            newcount = count - other[elem]
            if newcount > 0:
                result[elem] = newcount
        for elem, count in other.items():
            if elem not in self and count < 0:
                result[elem] = 0 - count
        return result