简体   繁体   English

元素相同的两个列表中的公共元素

[英]common elements in two lists where elements are the same

I have two lists like thw following: 我有两个类似以下的列表:

a=['not','not','not','not']
b=['not','not']

and I have to find the len of the list containing the intesection of the two above list, so that the result is: 并且我必须找到包含上面两个列表的整数的列表的len ,这样结果是:

intersection=['not','not']
len(intersection)
2

Now the problem is that I have tried filter(lambda x: x in a,b) and filter (lambda x: x in b,a) but when one of two list in longer than the other I do not get an intersection but just a membership checking. 现在的问题是我尝试过filter(lambda x: x in a,b)filter (lambda x: x in b,a)但是当两个列表中的一个比另一个更长时,我没有得到交集,而只是成员资格检查。 In the example above, since all the members of a are in b I get a len of common elements of 4; 在上面的示例中,由于a的所有成员都在b中,因此我得到了4个公共元素的len; what I instead want is the intersection, which is len 2. Using set().intersection(set()) would instead create a set, which is not what I want since all the elements are the same. 相反,我想要的是相交,即len 。使用set().intersection(set())会创建一个集,这不是我想要的,因为所有元素都相同。 Can you suggest me any valuable and compact solution to the problem? 您能建议我任何有价值且紧凑的解决方案吗?

If you don't mind using collections.Counter , then you could have a solution like 如果您不介意使用collections.Counter ,则可以采用类似的解决方案

>>> import collections
>>> a=['not','not','not','not']
>>> b=['not','not']

>>> c1 = collections.Counter(a)
>>> c2 = collections.Counter(b)

and then index by 'not' 然后按“不”索引

>>> c1['not'] + c2['not']
6

For the intersection, you need to 对于十字路口,您需要

>>> (c1 & c2) ['not']
2

I don't see any particularly compact way to compute this. 我看不出任何特别紧凑的方式来计算此值。 Let's just go for a solution first. 我们只是去寻求解决方案第一。

The intersection is some sublist of the shorter list (eg b ). intersection是较短列表的某个子列表(例如b )。 Now, for better performance when the shorter list is not extremely short, make the longer list a set (eg set(a) ). 现在,为了在较短的列表不是非常短的情况下获得更好的性能,请将较长的列表设置为一个集合(例如set(a) )。 The intersection can then be expressed as a list comprehension of those items in the shorter list which are also in the longer set: 然后,交集可以表示为较短列表中的那些条目的列表理解,这些条目也位于较长集合中:

def common_elements(a, b):
    shorter, longer = (a, b) if len(a)<len(b) else (b, a)
    longer = set(longer)
    intersection = [item for item in shorter if item in longer]
    return intersection

a = ['not','not','not','not']
b = ['not','not']
print(common_elements(a,b))

Do it by set . 通过set First make those lists to sets and then take their intersection. 首先将这些列表设为集合,然后进行交集。 Now there might be repetitions in the intersection. 现在路口可能有重复。 So for each elements in intersection take the minimum repetitions in a and b . 因此,对于相交的每个元素,请在ab进行最小重复。

>>> a=['not','not','not','not']
>>> b=['not','not']
>>> def myIntersection(A,B):
...     setIn = set(A).intersection(set(B))
...     rt = []
...     for i in setIn:
...         for j in range(min(A.count(i),B.count(i))):
...             rt.append(i)
...     return rt
...
>>> myIntersection(a,b)
['not', 'not']

Have you considered the following approach? 您是否考虑过以下方法?

a = ['not','not','not','not']
b = ['not','not']

min(len(a), len(b))
# 2

Since all the elements are the same, the number of common elements is just the minimum of the lengths of both lists. 由于所有元素都相同,因此公共元素的数量仅为两个列表长度的最小值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM