Python实现数据的计数

什么是计数

  1. 计数是一个重复加(或减)1的数学行为,通常用于算出对象有多少个或放置想要之数目个对象(对第一个对象从一算起,且将剩下的对象和由二开始的自然数做一对一对应)。计数可以是任何整数值,包括零或负计数。
  2. 举个例子,有一个列表['a','a','a','b','b','b','c','c','c'],对其进行计数,也就是统计里面的元素出现了多少次,例如'a'出现了3次。

Python实现数据的计数

  1. 正常情况下,我们可以使用for或者while循环方法,对数据进行循环遍历计数,代码如下:
  1. def count(nums):
  2. vars = dict()
  3. A, B, C = 0, 0 ,0 # A代表a出现的次数,B代表b出现的次数,C代表c出现的次数,
  4. for i in nums:
  5. if i == 'a':
  6. A = A + 1 # i为a,a出现的次数加1
  7. if i == 'b':
  8. B = B + 1 # i为b,b出现的次数加1
  9. if i == 'c':
  10. C = C + 1 # i为c,c出现的次数加1
  11. vars['a'] = A
  12. vars['b'] = B
  13. vars['c'] = C
  14. return vars
  15. print(count(['a','a','a','b','b','b','c','c','c']))
  1. 运行结果:
  1. {'b': 3, 'c': 3, 'a': 3} # 键为出现的元素,值为出现的元素的次数
  1. 很明显,用for循环方法的时间复杂度是O(n),当列表中的元素十分大时就需要花费很多的时间。所以,Python也提供了count()方法来实现计数。
  1. def func(nums):
  2. set1 = set(nums) # 利用集合统计出现过的元素
  3. dict_c = dict() # 创建字典存储每个元素及其出现次数
  4. for i in set1:
  5. dict_c[i] = nums.count(i)
  6. return dict_c
  7. print(func(['a','a','a','b','b','b','c','c','c']))
  1. 运行结果:
  1. {'b': 3, 'c': 3, 'a': 3}
  1. 可以看出用count()方法进行计数很方便,但是这还不是最好的方法。不管是for循环还是count()方法,在对几十个或者几百个元素进行计数时,就已经会增加很大的代码量。比如在一个列表中,11000都出现了一千次,此时我们并不知道这些元素到底出现了多少次,如果我们使用for循环或者count()方法,此时的代码量就已经是几千行了。那么Python中是否还存在更好的方法呢?
  2. 为了解决这样的问题,强大的Python还为我们提供了更好的方法。

collections.Counter()

Counter()实现计数

  1. collectionsPython的第三方模块,这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set tuple 的替代选择。
  2. collection模块中,Counter对象实现快速切方便的计数。先看看collection.Counter()的效果。
  1. from collections import Counter
  2. nums = Counter(['a','a','a','b','b','b','c','c','c'])
  3. print(nums)
  1. 运行结果:
  1. Counter({'a': 3, 'b': 3, 'c': 3})
  1. 可以看出,Counter()对象会对列表中所有相同的元素进行计数,返回一个集合,集合中的元素存储为字典键,其中键为进行计数的元素,值为每个元素的出现次数。
  2. Counter()对象不仅可以实现快速、方便的计数,还提供了三种方法实现别的功能。

elements()

  1. elements()会返回一个迭代器遍历元素,每个元素重复其次数。元素按首先遇到的顺序返回。如果一个元素的数量为零或者负数,elements()将忽略它。
  2. 当我们需要根据元素出现的次数去创建容器时,使用elements()方法的代码如下:
  1. from collections import Counter
  2. c = Counter(a=3,b=2,c=1,d=0)
  3. print(list(c.elements()))
  1. 运行结果:
  1. ['a', 'a', 'a', 'b', 'b', 'c'] #d的次数为0,所以忽略

而我们用常规的for循环方法的代码相对较多,且时间复杂度增大:

  1. def func(nums):
  2. dp = []
  3. for i in nums:
  4. dp += [i]*nums[i]
  5. return dp
  6. print(func({'a':3,'b':2,'c':1,'d':0}))

most_common([n])

  1. most_common([n])返回n个最常见元素的列表及其从最常见到最小的计数。如果不指定n的值,most_common([n])会返回计数器中的所有元素。如果元素具有相等计数,会按首先遇到的顺序排序。
  1. from collections import Counter
  2. nums = Counter('aaabbccdef').most_common(3)
  3. print(nums)
  1. 运行结果:
  1. [('a', 3), ('b', 2), ('c', 2)]

collections.Counter()使用手册:https://docs.python.org/zh-cn/3.7/library/collections.html#collections.Counter