user1718064
user1718064

Reputation: 475

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?

Upvotes: 1

Views: 255

Answers (4)

ersran9
ersran9

Reputation: 978

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

Upvotes: 1

rnbguy
rnbguy

Reputation: 1399

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']

Upvotes: 0

user2286078
user2286078

Reputation:

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.

Upvotes: 0

unutbu
unutbu

Reputation: 879113

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

Upvotes: 0

Related Questions