Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection of two Counters

I'm trying to find the shared elements (and the shared number of occurrences) between two lists. For example, the intersection of these two lists:

a = [1, 1, 2, 3, 4, 5, 6, 7, 8, 1]
b = [1, 1, 3, 5, 7, 9]

should return Counter({1: 2, 3: 1, 5: 1, 7: 1}) or something similar, e.g. {1: 2, 3: 1, 5: 1, 7: 1} or [1, 1, 3, 5, 7] (order of the list doesn't matter).

I already have an approach that works:

cnts_a = Counter(a)
cnts_b = Counter(b)
cnts_a_b = Counter()  # counter for the shared values
for key in set(cnts_a).intersection(cnts_b):
    cnts_a_b[key] = min(cnts_a[key], cnts_b[key])

But perhaps there is an easier (or faster) way?

like image 367
MSeifert Avatar asked May 16 '17 22:05

MSeifert


2 Answers

Use & for intersection:

>>> Counter(a) & Counter(b)
Counter({1: 2, 3: 1, 5: 1, 7: 1})

From docs:

Intersection(&) and union(|) return the minimum and maximum of corresponding counts.

like image 67
Ashwini Chaudhary Avatar answered Oct 24 '22 21:10

Ashwini Chaudhary


Instead of

cnts_a_b = Counter()  # counter for the shared values
for key in set(cnts_a).intersection(cnts_b):
    cnts_a_b[key] = min(cnts_a[k], cnts_b[k])

use

cnts_a_b = cnts_a & cnts_b

as & means the intersection of the Counter objects.

like image 39
MarianD Avatar answered Oct 24 '22 21:10

MarianD