简体   繁体   中英

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:

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. In the example above, since all the members of a are in b I get a len of common elements of 4; 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. 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

>>> 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 ). Now, for better performance when the shorter list is not extremely short, make the longer list a set (eg 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 . 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 .

>>> 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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