问题

《Python Cookbook》中有这么一个问题,给定一个序列,找出该序列出现次数最多的元素。
例如:

  1. words = [
  2. 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
  3. 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
  4. 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
  5. 'my', 'eyes', "you're", 'under'
  6. ]

统计出words中出现次数最多的元素?

初步探讨

1、collections模块的Counter类
首先想到的是collections模块的Counter类,具体用法看这里!具体用法看这里!具体用法看这里!https://docs.python.org/3.6/l...,重要的事情强调三遍。

  1. from collections import Counter
  2.  
  3. words = [
  4. 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
  5. 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
  6. 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
  7. 'my', 'eyes', "you're", 'under'
  8. ]
  9.  
  10. counter_words = Counter(words)
  11. print(counter_words)
  12. most_counter = counter_words.most_common(1)
  13. print(most_counter)

关于most_common([n]):

2、根据dict键值唯一性和sorted()函数

  1. import operator
  2.  
  3. words = [
  4. 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
  5. 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
  6. 'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
  7. 'my', 'eyes', "you're", 'under'
  8. ]
  9.  
  10. dict_num = {}
  11. for item in words:
  12. if item not in dict_num.keys():
  13. dict_num[item] = words.count(item)
  14.  
  15. # print(dict_num)
  16.  
  17. most_counter = sorted(dict_num.items(),key=lambda x: x[1],reverse=True)[0]
  18. print(most_counter)

sorted函数:
传送门:https://docs.python.org/3.6/l...

iterable:可迭代类型;
key:用列表元素的某个属性或函数进行作为关键字,有默认值,迭代集合中的一项;
reverse:排序规则. reverse = True 降序 或者 reverse = False 升序,有默认值。
返回值:是一个经过排序的可迭代类型,与iterable一样。

这里,我们使用匿名函数key=lambda x: x[1]
等同于:

  1. def key(x):
  2. return x[1]

这里,我们利用每个元素出现的次数进行降序排序,得到的结果的第一项就是出现元素最多的项。

更进一步

这里给出的序列很简单,元素的数目很少,但是有时候,我们的列表中可能存在上百万上千万个元素,那么在这种情况下,不同的解决方案是不是效率就会有很大差别了呢?
为了验证这个问题,我们来生成一个随机数列表,元素个数为一百万个。
这里使用numpy Package,使用前,我们需要安装该包,numpy包下载地址:https://pypi.python.org/pypi/...。这里我们环境是centos7,选择numpy-1.14.2.zip (md5, pgp)进行下载安装,解压后python setup.py install

  1. def generate_data(num=1000000):
  2. return np.random.randint(num / 10, size=num)

np.random.randint(low[, high, size]) 返回随机的整数,位于半开区间 [low, high)
具体用法参考https://pypi.python.org/pypi

OK,数据生成了,让我们来测试一下两个方法所消耗的时间,统计时间,我们用time函数就可以。

  1. #!/usr/bin/python
  2. # coding=utf-8
  3. #
  4. # File: most_elements.py
  5. # Author: ralap
  6. # Data: 2018-4-5
  7. # Description: find most elements in list
  8. #
  9.  
  10. from collections import Counter
  11. import operator
  12. import numpy as np
  13. import random
  14. import time
  15.  
  16. def generate_data(num=1000000):
  17. return np.random.randint(num / 10, size=num)
  18.  
  19. def collect(test_list):
  20. counter_words = Counter(test_list)
  21. print(counter_words)
  22. most_counter = counter_words.most_common(1)
  23. print(most_counter)
  24.  
  25. def list_to_dict(test_list):
  26. dict_num = {}
  27. for item in test_list:
  28. if item not in dict_num.keys():
  29. dict_num[item] = test_list.count(item)
  30.  
  31. most_counter = sorted(dict_num.items(), key=lambda x: x[1], reverse=True)[0]
  32. print(most_counter)
  33.  
  34. if __name__ == "__main__":
  35. list_value = list(generate_data())
  36.  
  37. t1 = time.time()
  38. collect(list_value)
  39. t2 = time.time()
  40. print("collect took: %sms" % (t2 - t1))
  41.  
  42. t1 = t2
  43. list_to_dict(list_value)
  44. t2 = time.time()
  45. print("list_to_dict took: %sms" % (t2 - t1))

以下结果是我在自己本地电脑运行结果,主要是对比两个方法相对消耗时间。

当数据比较大时,消耗时间差异竟然如此之大!下一步会进一步研究Counter的实现方式,看看究竟是什么魔法让他性能如此好。

参考资料

https://blog.csdn.net/xie_0723/article/details/51692806

【python cookbook】找出序列中出现次数最多的元素的更多相关文章

  1. 【python cookbook】【数据结构与算法】12.找出序列中出现次数最多的元素

    问题:找出一个元素序列中出现次数最多的元素是什么 解决方案:collections模块中的Counter类正是为此类问题所设计的.它的一个非常方便的most_common()方法直接告诉你答案. # ...

  2. Python实用黑科技——找出序列里面出现次数最多的元素

    需求: 如何从一个序列中快速获取出现次数最多的元素. 方法: 利用collections.Counter类可以解决这个问题,特别是他的most_common()方法更是处理此问题的最快途径.比如,现在 ...

  3. Java实现找出数组中重复次数最多的元素以及个数

    /**数组中元素重复最多的数 * @param array * @author shaobn * @param array */ public static void getMethod_4(int[ ...

  4. [PY3]——找出一个序列中出现次数最多的元素/collections.Counter 类的用法

    问题 怎样找出一个序列中出现次数最多的元素呢? 解决方案 collections.Counter 类就是专门为这类问题而设计的, 它甚至有一个有用的 most_common() 方法直接给了你答案 c ...

  5. 剑指Offer:找出数组中出现次数超过一半的元素

    题目:找出数组中出现次数超过一半的元素 解法:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半 #include <stdio.h> int ha ...

  6. python之Counter类:计算序列中出现次数最多的元素

    Counter类:计算序列中出现次数最多的元素 from collections import Counter c = Counter('abcdefaddffccef') print('完整的Cou ...

  7. Python中用max()筛选出列表中出现次数最多的元素

    1 List = [1,2,3,4,2,3,2] # 随意创建一个只有数字的列表 2 maxTimes = max(List,key=List.count) # maxTimes指列表中出现次数最多的 ...

  8. python 找出字符串中出现次数最多的字母

    # 请大家找出s=”aabbccddxxxxffff”中 出现次数最多的字母 # 第一种方法,字典方式: s="aabbccddxxxxffff" count ={} for i ...

  9. js常会问的问题:找出字符串中出现次数最多的字符。

    一.循环obj let testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd'; function getMax(str) { let obj = {}; for(le ...

随机推荐

  1. 关于Image模块的调色板

    参考:https://blog.csdn.net/zhangziju/article/details/79123275 https://blog.csdn.net/qq_21239003/articl ...

  2. SAS如何看待大数据

    SAS如何看待大数据 "大数据"现在是一个炙手可热的词语,数据分析师这个词虽然比较新,但收集与存储大量信息的历史却不短了. 早在本世纪初,行业分析师Doug Laney就提出了&q ...

  3. 改进初学者的PID-介绍

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  4. LeetCode_371. Sum of Two Integers

    371. Sum of Two Integers Easy Calculate the sum of two integers a and b, but you are not allowed to ...

  5. Vue cli4.0 代理配置

    proxy: { '/service': { target: 'http://192.168.40.243:3000/', //对应自己的接口 changeOrigin: true, ws: true ...

  6. 无限级分类,抓取某元素的所有下级id

    mysql> select id,invite_qke_id from tf_qke; +----+---------------+ | id | invite_qke_id | +----+- ...

  7. 使用Jedis出现Connection refused的解决方案

    1.修改redis.conf配置文件中的   bind 127.0.0.1  为本机外网IP: 2. cluster-enabled yes  设置是否集群操作,如果是的话开启 yes,否的话 设置n ...

  8. Eclipse导war包忽略node_modules等文件

    window7环境下,选择project->Properties->如下图

  9. Extjs locked无效,使用enableLocking即可

    一.前言 在使用 extjs 做表格时,由于表格的列太多,我们需要设置一些固定列来查看数据,所以我们需要用到 locked 属性.普通加载 columns 的列是有效的,如果是动态加载的话,使用 lo ...

  10. 搭建Springboot

    这几天一直在研究IDEA上面怎么搭建一个web-mvc的SpringBoot项目,看网上的教程一步步的搭建,可是还是出现一堆的问题. 为了让大家以后少走一些弯路,我在这里分享一下我这几天研究的成果,也 ...