If you only want one item’s count, use the count method:
>>> [1, 2, 3, 4, 1, 4, 1].count(1)
3
Don’t use this if you want to count multiple items. Calling count in a loop requires a separate pass over the list for every count call, which can be catastrophic for performance. If you want to count all items, or even just multiple items, use Counter, as explained in the other answers.
from __future__ import print_function
import timeit
t1=timeit.Timer('Counter(l)', \
'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]')
t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]','import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]')print("Counter(): ", t1.repeat(repeat=3,number=10000))print("count(): ", t2.repeat(repeat=3,number=10000)
For counting the occurrences of just one list item you can use count()
>>> l = ["a","b","b"]
>>> l.count("a")
1
>>> l.count("b")
2
Counting the occurrences of all items in a list is also known as “tallying” a list, or creating a tally counter.
Counting all items with count()
To count the occurrences of items in l one can simply use a list comprehension and the count() method
[[x,l.count(x)] for x in set(l)]
(or similarly with a dictionary dict((x,l.count(x)) for x in set(l)))
Example:
>>> l = ["a","b","b"]
>>> [[x,l.count(x)] for x in set(l)]
[['a', 1], ['b', 2]]
>>> dict((x,l.count(x)) for x in set(l))
{'a': 1, 'b': 2}
Counting all items with Counter()
Alternatively, there’s the faster Counter class from the collections library
Counter(l)
Example:
>>> l = ["a","b","b"]
>>> from collections import Counter
>>> Counter(l)
Counter({'b': 2, 'a': 1})
How much faster is Counter?
I checked how much faster Counter is for tallying lists. I tried both methods out with a few values of n and it appears that Counter is faster by a constant factor of approximately 2.
Here is the script I used:
from __future__ import print_function
import timeit
t1=timeit.Timer('Counter(l)', \
'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
)
t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]',
'import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]'
)
print("Counter(): ", t1.repeat(repeat=3,number=10000))
print("count(): ", t2.repeat(repeat=3,number=10000)
>>> c2 =Counter(list('aabbxyz'))>>> c - c2 # set differenceCounter({'a':3,'c':3,'b':2,'d':2,'e':1})>>> c + c2 # addition of all elementsCounter({'a':7,'b':6,'c':3,'d':2,'e':1,'y':1,'x':1,'z':1})>>> c | c2 # set unionCounter({'a':5,'b':4,'c':3,'d':2,'e':1,'y':1,'x':1,'z':1})>>> c & c2 # set intersectionCounter({'a':2,'b':2})
This works fine for any list. Tuples have this method as well:
>>> t = tuple('aabbbffffff')
>>> t
('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f')
>>> t.count('f')
6
collections.Counter
And then there’s collections.Counter. You can dump any iterable into a Counter, not just a list, and the Counter will retain a data structure of the counts of the elements.
Usage:
>>> from collections import Counter
>>> c = Counter(l)
>>> c['b']
4
Counters are based on Python dictionaries, their keys are the elements, so the keys need to be hashable. They are basically like sets that allow redundant elements into them.
Further usage of collections.Counter
You can add or subtract with iterables from your counter:
import pandas as pd
l =['a','b','c','d','a','d','a']# converting the list to a Series and counting the values
my_count = pd.Series(l).value_counts()
my_count
import pandas as pd
l = ['a', 'b', 'c', 'd', 'a', 'd', 'a']
# converting the list to a Series and counting the values
my_count = pd.Series(l).value_counts()
my_count
Output:
a 3
d 2
b 1
c 1
dtype: int64
If you are looking for a count of a particular element, say a, try:
my_count['a']
Output:
3
回答 10
我今天遇到了这个问题,在考虑检查SO之前推出了自己的解决方案。这个:
dict((i,a.count(i))for i in a)
对于大型列表,真的非常慢。我的解决方案
def occurDict(items):
d ={}for i in items:if i in d:
d[i]= d[i]+1else:
d[i]=1return d
# Python >= 2.6 (defaultdict) && < 2.7 (Counter, OrderedDict)
from collections import defaultdict
def count_unsorted_list_items(items):
"""
:param items: iterable of hashable items to count
:type items: iterable
:returns: dict of counts like Py2.7 Counter
:rtype: dict
"""
counts = defaultdict(int)
for item in items:
counts[item] += 1
return dict(counts)
# Python >= 2.2 (generators)
def count_sorted_list_items(items):
"""
:param items: sorted iterable of items to count
:type items: sorted iterable
:returns: generator of (item, count) tuples
:rtype: generator
"""
if not items:
return
elif len(items) == 1:
yield (items[0], 1)
return
prev_item = items[0]
count = 1
for item in items[1:]:
if prev_item == item:
count += 1
else:
yield (prev_item, count)
count = 1
prev_item = item
yield (item, count)
return
import unittest
class TestListCounters(unittest.TestCase):
def test_count_unsorted_list_items(self):
D = (
([], []),
([2], [(2,1)]),
([2,2], [(2,2)]),
([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
)
for inp, exp_outp in D:
counts = count_unsorted_list_items(inp)
print inp, exp_outp, counts
self.assertEqual(counts, dict( exp_outp ))
inp, exp_outp = UNSORTED_WIN = ([2,2,4,2], [(2,3), (4,1)])
self.assertEqual(dict( exp_outp ), count_unsorted_list_items(inp) )
def test_count_sorted_list_items(self):
D = (
([], []),
([2], [(2,1)]),
([2,2], [(2,2)]),
([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]),
)
for inp, exp_outp in D:
counts = list( count_sorted_list_items(inp) )
print inp, exp_outp, counts
self.assertEqual(counts, exp_outp)
inp, exp_outp = UNSORTED_FAIL = ([2,2,4,2], [(2,3), (4,1)])
self.assertEqual(exp_outp, list( count_sorted_list_items(inp) ))
# ... [(2,2), (4,1), (2,1)]
回答 12
以下是三种解决方案:
最快的是使用for循环并将其存储在Dict中。
import time
from collections importCounterdef countElement(a):
g ={}for i in a:if i in g:
g[i]+=1else:
g[i]=1return g
z =[1,1,1,1,2,2,2,2,3,3,4,5,5,234,23,3,12,3,123,12,31,23,13,2,4,23,42,42,34,234,23,42,34,23,423,42,34,23,423,4,234,23,42,34,23,4,23,423,4,23,4]#Solution 1 - Faster
st = time.monotonic()for i in range(1000000):
b = countElement(z)
et = time.monotonic()print(b)print('Simple for loop and storing it in dict - Duration: {}'.format(et - st))#Solution 2 - Fast
st = time.monotonic()for i in range(1000000):
a =Counter(z)
et = time.monotonic()print(a)print('Using collections.Counter - Duration: {}'.format(et - st))#Solution 3 - Slow
st = time.monotonic()for i in range(1000000):
g = dict([(i, z.count(i))for i in set(z)])
et = time.monotonic()print(g)print('Using list comprehension - Duration: {}'.format(et - st))
结果
#Solution 1 - Faster
{1:4,2:5,3:4,4:6,5:2,234:3,23:10,12:2,123:1,31:1,13:1,42:5,34:4,423:3}Simplefor loop and storing it in dict -Duration:12.032000000000153
Fastest is using a for loop and storing it in a Dict.
import time
from collections import Counter
def countElement(a):
g = {}
for i in a:
if i in g:
g[i] +=1
else:
g[i] =1
return g
z = [1,1,1,1,2,2,2,2,3,3,4,5,5,234,23,3,12,3,123,12,31,23,13,2,4,23,42,42,34,234,23,42,34,23,423,42,34,23,423,4,234,23,42,34,23,4,23,423,4,23,4]
#Solution 1 - Faster
st = time.monotonic()
for i in range(1000000):
b = countElement(z)
et = time.monotonic()
print(b)
print('Simple for loop and storing it in dict - Duration: {}'.format(et - st))
#Solution 2 - Fast
st = time.monotonic()
for i in range(1000000):
a = Counter(z)
et = time.monotonic()
print (a)
print('Using collections.Counter - Duration: {}'.format(et - st))
#Solution 3 - Slow
st = time.monotonic()
for i in range(1000000):
g = dict([(i, z.count(i)) for i in set(z)])
et = time.monotonic()
print(g)
print('Using list comprehension - Duration: {}'.format(et - st))
Result
#Solution 1 - Faster
{1: 4, 2: 5, 3: 4, 4: 6, 5: 2, 234: 3, 23: 10, 12: 2, 123: 1, 31: 1, 13: 1, 42: 5, 34: 4, 423: 3}
Simple for loop and storing it in dict - Duration: 12.032000000000153
from itertools import groupby
L =['a','a','a','t','q','a','d','a','d','c']# Input list
counts =[(i, len(list(c)))for i,c in groupby(L)]# Create value-count pairs as list of tuples print(counts)
Antoher possiblity for getting the count of all elements in the list could be by means of itertools.groupby().
With “duplicate” counts
from itertools import groupby
L = ['a', 'a', 'a', 't', 'q', 'a', 'd', 'a', 'd', 'c'] # Input list
counts = [(i, len(list(c))) for i,c in groupby(L)] # Create value-count pairs as list of tuples
print(counts)
Notice how it combined the first three a‘s as the first group, while other groups of a are present further down the list. This happens because the input list L was not sorted. This can be a benefit sometimes if the groups should in fact be separate.
With unique counts
If unique group counts are desired, just sort the input list:
counts = [(i, len(list(c))) for i,c in groupby(sorted(L))]
print(counts)
Note: For creating unique counts, many of the other answers provide easier and more readable code compared to the groupby solution. But it is shown here to draw a parallel to the duplicate count example.
It was suggested to use numpy’s bincount, however it works only for 1d arrays with non-negative integers. Also, the resulting array might be confusing (it contains the occurrences of the integers from min to max of the original list, and sets to 0 the missing integers).
A better way to do it with numpy is to use the unique function with the attribute return_counts set to True. It returns a tuple with an array of the unique values and an array of the occurrences of each unique value.
To count the number of diverse elements having a common type:
li = ['A0','c5','A8','A2','A5','c2','A3','A9']
print sum(1 for el in li if el[0]=='A' and el[1] in '01234')
gives
3 , not 6
回答 16
虽然这是一个非常古老的问题,但是由于我没有找到一支,所以我做了一支。
# original numbers in list
l =[1,2,2,3,3,3,4]# empty dictionary to hold pair of number and its count
d ={}# loop through all elements and store count[ d.update({i:d.get(i,0)+1})for i in l ]print(d)
Although it is very old question, but as i didn’t find a one liner, i made one.
# original numbers in list
l = [1, 2, 2, 3, 3, 3, 4]
# empty dictionary to hold pair of number and its count
d = {}
# loop through all elements and store count
[ d.update( {i:d.get(i, 0)+1} ) for i in l ]
print(d)
def countfrequncyinarray(arr1):
r=len(arr1)
return {i:arr1.count(i) for i in range(1,r+1)}
arr1=[4,4,4,4]
a=countfrequncyinarray(arr1)
print(a)
回答 23
l2=[1,"feto",["feto",1,["feto"]],['feto',[1,2,3,['feto']]]]
count=0defTest(l):global count
if len(l)==0:return count
count=l.count("feto")for i in l:if type(i)is list:
count+=Test(i)return count
print(Test(l2))
l2=[1,"feto",["feto",1,["feto"]],['feto',[1,2,3,['feto']]]]
count=0
def Test(l):
global count
if len(l)==0:
return count
count=l.count("feto")
for i in l:
if type(i) is list:
count+=Test(i)
return count
print(Test(l2))
this will recursive count or search for the item in the list even if it in list of lists