Python 3 - 计算两个列表中的匹配项(包括重复项)

时间:2012-11-10 16:37:13

标签: python python-3.x

首先,我是编程和python的新手,我已经看过这里,但无法找到解决方案,如果这是一个愚蠢的问题,请原谅我!

我有两个列表,我试图确定第二个列表中的项目出现在第一个列表中的次数。

我有以下解决方案:

    list1 = ['black','red','yellow']
    list2 = ['the','big','black','dog']
    list3 = ['the','black','black','dog']
    p = set(list1)&set(list2)
    print(len(p))

除了第二个列表包含重复项之外,它还可以正常工作。

即。上面的list1和list2返回1,但list1和list3也是如此,理想情况下应返回2

有人可以建议解决这个问题吗?任何帮助将不胜感激!

谢谢,

亚当

4 个答案:

答案 0 :(得分:5)

由于您使用sets作为集合类型,因此您会看到此问题。集合有两个特征:它们是无序的(这在这里无关紧要),它们的元素是唯一的。因此,在将它们转换为集合之前,您甚至会丢失列表中的重复项,甚至在找到它们的交集之前:

>>> p = ['1', '2', '3', '3', '3', '3', '3']
>>> set(p)
set(['1', '2', '3'])

您可以通过多种方式执行此处要执行的操作,但您需要先查看列表count方法。我会做这样的事情:

>>> list1 = ['a', 'b', 'c']
>>> list2 = ['a', 'b', 'c', 'c', 'c']
>>> results = {}
>>> for i in list1:
        results[i] = list2.count(i) 
>>> results
{'a': 1, 'c': 3, 'b': 1}

此方法创建字典(results),并为list1中的每个元素在results中创建一个键,计算它在list2中出现的次数,以及将其分配给密钥的值。

编辑:正如Lattyware所指出的,这种方法解决的问题与您提出的问题略有不同。一个真正基本的解决方案看起来像这样

>>> words = ['red', 'blue', 'yellow', 'black']
>>> list1 = ['the', 'black', 'dog']
>>> list2 = ['the', 'blue', 'blue', 'dog']
>>> results1 = 0
>>> results2 = 0
>>> for w in words:
        results1 += list1.count(w)
        results2 += list2.count(w)

>>> results1
1
>>> results2
2

这与我的第一个建议类似:它遍历主列表中的每个单词(这里我使用words),将list1中显示的次数添加到计数器results1list2results2

如果您需要的信息不仅仅是重复数量,您还需要使用字典,或者更好的是Counter模块中的专用collections类型。计数器旨在使我在上面的示例中所做的一切变得容易。

>>> from collections import Counter
>>> results3 = Counter()
>>> for w in words:
        results3[w] = list2.count(w)

>>> results3
Counter({'blue': 2, 'black': 0, 'yellow': 0, 'red': 0})
>>> sum(results3.values())
2

答案 1 :(得分:4)

不应该列出1而列表2会返回0吗?或者你的意思是

list1 = ['black', 'red', 'yellow']

我想,你想要的是

print(len([w for w in list2 if w in list1]))

使用集合的问题是集合没有重复。实际上,使用集合的通常原因是消除重复。当然,这就是你不想要的。

答案 2 :(得分:1)

我知道这是一个古老的问题,但是如果有人想知道如何从一个或多个列表中获取匹配项或匹配项的长度。您也可以这样做。

a = [1,2,3]
b = [2,3,4]
c = [2,4,5]

要获得两个列表中的匹配项,请说a和b为

d = [value for value in a if value in b] # 2,3 

对于这三个列表,将是

d = [value for value in a if value in b and value in c] # 2
len(d) # to get the number of matches

此外,如果您需要处理重复项。只需将列表转换为一组即可,例如

a  = set(a) # and so on

答案 3 :(得分:0)

如果您的意思是想要计算list2中list1元素的频率,那么这个解决方案可能适合您:

list1 = ['black', 'red', 'yellow']
list2 = ['the', 'big', 'black', 'dog']
list3 = ['the', 'black', 'black', 'dog']

首先我们可以计算list2中元素的频率并构造一个dict,然后我们可以根据list1从dict构造一个子句,并得到你的总频率可以计算sub_dct的值:

# count the frequency of elements of list1 in list2
def cntFrequency(lst1,lst2):
    dct=dict(Counter(lst2))
    sub_dct={k:dct.get(k,0) for k in lst1}
    return sub_dct

,结果如下:

from collections import Counter

cnt_dct=cntFrequency(list1,list2)
print cnt_dct
print sum(cnt_dct.values())

# Output
{'black': 1, 'yellow': 0, 'red': 0}
1