如何统计列表项的发生?

给定一个项目,我怎样才能在Python列表中计算它的出现?

>>> [1, 2, 3, 4, 1, 4, 1].count(1) 3 

如果您使用的是Python 2.7或3,并且您希望每个元素的出现次数为:

 >>> from collections import Counter >>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red'] >>> Counter(z) Counter({'blue': 3, 'red': 2, 'yellow': 1}) 

计算列表中一个项目的出现次数

为了统计只有一个列表项的出现,你可以使用count()

 >>> l = ["a","b","b"] >>> l.count("a") 1 >>> l.count("b") 2 

统计列表中所有项目的出现次数也称为“统计”列表或创build计数器计数器。

用count()计算所有项目

要计算项目的出现次数,可以简单地使用列表理解和count()方法

 [[x,l.count(x)] for x in set(l)] 

(或类似地用dict((x,l.count(x)) for x in set(l))的字典dict((x,l.count(x)) for x in set(l))

例:

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

用Counter()计数所有项目

或者,从collections库中有更快的Counter

 Counter(l) 

例:

 >>> l = ["a","b","b"] >>> from collections import Counter >>> Counter(l) Counter({'b': 2, 'a': 1}) 

Counter有多快?

我查了多lessCounter是统计清单。 我用n的几个值来尝试两种方法,看起来, Counter以大约2的常数因子更快。

这是我使用的脚本:

 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) 

而输出:

 Counter(): [0.46062711701961234, 0.4022796869976446, 0.3974247490405105] count(): [7.779430688009597, 7.962715800967999, 8.420845870045014] 

另一种方法来获取每个项目的出现次数,在一个字典中:

 dict((i, a.count(i)) for i in a) 

list.count(x)返回x出现在列表中的次数

请参阅: http : //docs.python.org/tutorial/datastructures.html#more-on-lists

如果你想一次统计所有的值,你可以使用numpy数组和bincount非常快bincount按照如下步骤进行

 import numpy as np a = np.array([1, 2, 3, 4, 1, 4, 1]) np.bincount(a) 

这使

 >>> array([0, 3, 1, 1, 2]) 

给定一个项目,我怎样才能在Python列表中计算它的出现?

这里是一个例子列表:

 >>> l = list('aaaaabbbbcccdde') >>> l ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e'] 

list.count

list.count方法

 >>> l.count('b') 4 

这适用于任何列表。 元组也有这个方法:

 >>> t = tuple('aabbbffffff') >>> t ('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f') >>> t.count('f') 6 

collections.Counter

然后有collections品。计数器。 您可以将任何迭代器转储到Counter中,而不仅仅是一个列表,Counter将保留一个元素计数的数据结构。

用法:

 >>> from collections import Counter >>> c = Counter(l) >>> c['b'] 4 

计数器是基于Python字典,它们的关键是元素,所以密钥需要可散列。 它们基本上就像允许多余的元素进入它们的集合。

计算器的进一步用法。 collections.Counter

您可以从计数器中添加或减去迭代次数:

 >>> c.update(list('bbb')) >>> c['b'] 7 >>> c.subtract(list('bbb')) >>> c['b'] 4 

您也可以使用计数器进行多套操作:

 >>> c2 = Counter(list('aabbxyz')) >>> c - c2 # set difference Counter({'a': 3, 'c': 3, 'b': 2, 'd': 2, 'e': 1}) >>> c + c2 # addition of all elements Counter({'a': 7, 'b': 6, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1}) >>> c | c2 # set union Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1}) >>> c & c2 # set intersection Counter({'a': 2, 'b': 2}) 

为什么不是pandas?

另一个答案表明:

为什么不使用pandas?

pandas是一个普通的图书馆,但它不在标准图​​书馆。 将它作为依赖添加是不重要的。

列表对象本身以及标准库中都有这种用例的内build解决scheme。

如果你的项目还不需要pandas,那么仅仅为了这个function而做它就是愚蠢的。

我今天有这个问题,并在我想检查SO之前推出了自己的解决scheme。 这个:

 dict((i,a.count(i)) for i in a) 

大列表真的很慢。 我的解决scheme

 def occurDict(items): d = {} for i in items: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d 

实际上比Counter解决scheme快一点,至less对于Python 2.7来说。

为什么不使用pandas?

 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 

输出:

 a 3 d 2 b 1 c 1 dtype: int64 

如果你正在寻找一个特定元素的数量,说一个 ,试试:

 my_count['a'] 

输出:

 3 
 # 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)] 

我已经将所有build议的解决scheme(和一些新的解决scheme)与perfplot (我的一个小项目)进行了比较。

一个项目

对于足够大的arrays,事实certificate

 numpy.sum(numpy.array(a) == 1) 

比其他解决scheme稍快。

在这里输入图像描述

计数所有项目

如前所述 ,

 numpy.bincount(a) 

是你想要的。

在这里输入图像描述


代码重现的情节:

 from collections import Counter from collections import defaultdict import numpy import operator import pandas import perfplot def counter(a): return Counter(a) def count(a): return dict((i, a.count(i)) for i in set(a)) def bincount(a): return numpy.bincount(a) def pandas_value_counts(a): return pandas.Series(a).value_counts() def occur_dict(a): d = {} for i in a: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d def count_unsorted_list_items(items): counts = defaultdict(int) for item in items: counts[item] += 1 return dict(counts) def operator_countof(a): return dict((i, operator.countOf(a, i)) for i in set(a)) perfplot.show( setup=lambda n: list(numpy.random.randint(0, 100, n)), n_range=[2**k for k in range(20)], kernels=[ counter, count, bincount, pandas_value_counts, occur_dict, count_unsorted_list_items, operator_countof ], equality_check=None, logx=True, logy=True, ) 

2。

 from collections import Counter from collections import defaultdict import numpy import operator import pandas import perfplot def counter(a): return Counter(a) def count(a): return dict((i, a.count(i)) for i in set(a)) def bincount(a): return numpy.bincount(a) def pandas_value_counts(a): return pandas.Series(a).value_counts() def occur_dict(a): d = {} for i in a: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d def count_unsorted_list_items(items): counts = defaultdict(int) for item in items: counts[item] += 1 return dict(counts) def operator_countof(a): return dict((i, operator.countOf(a, i)) for i in set(a)) perfplot.show( setup=lambda n: list(numpy.random.randint(0, 100, n)), n_range=[2**k for k in range(20)], kernels=[ counter, count, bincount, pandas_value_counts, occur_dict, count_unsorted_list_items, operator_countof ], equality_check=None, logx=True, logy=True, ) 

要计算具有通用types的不同元素的数量:

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

3 ,不是6

 from collections import Counter country=['Uruguay', 'Mexico', 'Uruguay', 'France', 'Mexico'] count_country = Counter(country) output_list= [] for i in count_country: output_list.append([i,count_country[i]]) print output_list 

输出列表:

 [['Mexico', 2], ['France', 1], ['Uruguay', 2]] 

您也可以使用内置模块operator countOf方法。

 >>> import operator >>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1) 3 
 sum([1 for elem in <yourlist> if elem==<your_value>]) 

这将返回your_value的出现量