Reputation: 759
a = list([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
b = list([1, 3, 6, 9])
How do I count the number of times an item in list be occurs in list a?
The above example should return a value of 4.
Whilst writing this question, I thought of the following (which appears to work)
a = list([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
b = list([1, 3, 6, 9])
c = 0
for n in b:
if n in a:
c += 1
continue
print (c)
But there must be a neater way using list comparisons or something?
Upvotes: 5
Views: 6116
Reputation: 411
While set works for unique
List comprehension considers duplicates as well
a = [1,1]
b = [1,1]
count = len(set(a) & set(b))
count2 = sum(i in b for i in a)
print(count, count2)
1 2
[Program finished]
Upvotes: 0
Reputation: 1664
Here are a few variations that count duplicates and ignore all values that aren't in b.
from collections import Counter
# a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
a = [1, 4, 3, 1, 2, 4, 4, 5, 6, 6, 7, 7, 7, 7, 8, 9, 0, 1]
b = [1, 3, 6, 9]
counts = Counter()
# make counts order match b order
for item in b:
counts[item] = 0
for item in a:
if item in b:
counts[item] += 1
print("in 'b' order")
print([(k, v) for k, v in counts.items()])
print("in descending frequency order")
print(counts.most_common())
print("count all occurrences in a of elements that are also in b")
print(sum(counts.values()))
python count_b_in_a.py
in 'b' order
[(1, 3), (3, 1), (6, 2), (9, 1)]
in descending frequency order
[(1, 3), (6, 2), (3, 1), (9, 1)]
count all occurrences in a of elements that are also in b
7
Responding to your comment about performance, here's a comparison between scanning a list and scanning a set in Python:
import datetime
def timestamp():
return datetime.datetime.now()
def time_since(t):
return (timestamp() - t).microseconds // 1000
a = list(range(1000_000))
b = set(a)
iterations = 10
t = timestamp()
for i in range(iterations):
c = 974_152 in a
print("Finished {iterations} iterations of list scan in {duration}ms"
.format(iterations=iterations, duration=time_since(t)))
t = timestamp()
for i in range(iterations):
c = 974_152 in b
print("Finished {iterations} iterations of set scan in {duration}ms"
.format(iterations=iterations, duration=time_since(t)))
python scan.py
Finished 10 iterations of list scan in 248ms
Finished 10 iterations of set scan in 0ms
First point to note: Python's no slouch at either. 1/4 second on an old laptop to scan 10 million list elements isn't bad. But it's still a linear scan.
Python sets are in a different class. If you take the // 1000
out of time_since()
, you'll see that Python scans a 1-million member set 10 times in under a microsecond. You'll find other set operations are also lightning fast. Wherever sets apply in Python, use them: they're fantastic.
And if you're contemplating applying the above code to much bigger lists, where performance matters, the first thing to do might be to convert b
to a set.
Upvotes: 2
Reputation: 24038
If you just want to count the number of elements that are in both lists (and you don't need to know how many times they occur in the other list) you can just use:
count = len(set(a).intersection(set(b)))
Or identically:
count = len(set(a) & set(b))
Upvotes: 3
Reputation: 20490
This one-liner should work as well. Find the count of each element and sum those counts up
op = sum([a.count(j) for j in b])
The outputs will be
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
b = [1, 3, 6, 9]
#4
a = [1, 1, 2, 3, 3, 3, 4, 5, 6, 6 , 7, 8, 9, 0]
b = [1, 3, 6, 9]
#8
Upvotes: 1
Reputation: 2614
Simple way using set
:
>>> len(set(a) & set(b))
4
This is an old question, take a look to: How can I compare two lists in python and return matches
Upvotes: 3
Reputation: 11073
Try this just in one line:
s = sum(a.count(i) for i in b if i in a)
s
will be 4
as output.
Also, it supports duplicate items in a
.
Upvotes: 2