问题

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

words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
]

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

初步探讨

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

from collections import Counter

words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
] counter_words = Counter(words)
print(counter_words)
most_counter = counter_words.most_common(1)
print(most_counter)

关于most_common([n]):

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

import operator

words = [
'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the',
'eyes', "don't", 'look', 'around', 'the', 'eyes', 'look', 'into',
'my', 'eyes', "you're", 'under'
] dict_num = {}
for item in words:
if item not in dict_num.keys():
dict_num[item] = words.count(item) # print(dict_num) most_counter = sorted(dict_num.items(),key=lambda x: x[1],reverse=True)[0]
print(most_counter)

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

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

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

def key(x):
return x[1]

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

更进一步

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

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

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

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

#!/usr/bin/python
# coding=utf-8
#
# File: most_elements.py
# Author: ralap
# Data: 2018-4-5
# Description: find most elements in list
# from collections import Counter
import operator
import numpy as np
import random
import time def generate_data(num=1000000):
return np.random.randint(num / 10, size=num) def collect(test_list):
counter_words = Counter(test_list)
print(counter_words)
most_counter = counter_words.most_common(1)
print(most_counter) def list_to_dict(test_list):
dict_num = {}
for item in test_list:
if item not in dict_num.keys():
dict_num[item] = test_list.count(item) most_counter = sorted(dict_num.items(), key=lambda x: x[1], reverse=True)[0]
print(most_counter) if __name__ == "__main__":
list_value = list(generate_data()) t1 = time.time()
collect(list_value)
t2 = time.time()
print("collect took: %sms" % (t2 - t1)) t1 = t2
list_to_dict(list_value)
t2 = time.time()
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. Nginx 504响应超时

    1.问题分析 nginx访问出现504 Gateway Time-out,一般是由于程序执行时间过长导致响应超时,例如程序需要执行90秒,而nginx最大响应等待时间为30秒,这样就会出现超时.    ...

  2. while死循环

    while死循环放入主线程要注意,如果处理不当可能引起界面假死,如果界面假死,可以放入子线程中(如果每个循环处理时间现对于CPU很短,则建议在本次循环结束的尾部加入Sleep以释放对CPU的占用) C ...

  3. lumen伪静态路由设置示例

    lumen路由文件中的配置: $app->get('info-{tid}.html', 'ThreadController@palmInfo'); 控制器中代码示例: public functi ...

  4. CentOS7为docker-ce配置阿里云镜像加速器

    一.找加速地址 https://promotion.aliyun.com/ntms/act/kubernetes.html 控制台 二.添加daemon.json 文件 vim /etc/docker ...

  5. 网站证书(SSL域名证书)常见格式使用

    主流的Web服务软件通常都基于两种基础密码库:OpenSSL和Java 1.Tomcat.Weblogic.JBoss等系统是使用Java提供的密码库.通过Java的Keytool工具,生成Java ...

  6. Kubernetes环境部署

    简介 Kubernetes 是一个开源系统,用于容器化应用的自动部署.扩缩和管理.它将构成应用的容器按逻辑单位进行分组以便于管理和发现.   配置镜像源 Debian / Ubuntu apt-get ...

  7. JavaScript图形实例:图形的旋转变换

    旋转变换:图形上的各点绕一固定点沿圆周路径作转动称为旋转变换.可用旋转角表示旋转量的大小. 旋转变换通常约定以逆时针方向为正方向.最简单的旋转变换是以坐标原点(0,0)为旋转中心,这时,平面上一点P( ...

  8. YCOJ过河卒C++

    过河卒是一道~~较简单 的问题,用递归或者动态规划都可以完成,但今天主要不是递归或者动态规划,而是用深度优先搜索做的.虽然会有两组TLE~~ 深搜是一种向下搜索的算法(如图所示) 它能有效的统计中点到 ...

  9. use azure-cli to manage resources

    登陆 注意: 在Azure China中使用Azure CLI 2.0之前,请首先切换环境, 运行: az cloud set -n AzureChinaCloud 如果想切回全球的版本: az cl ...

  10. apache 代理配置

    apache 2.4.6版本 <VirtualHost *:8080> ServerName 21.12.13.146 DocumentRoot /root/gbhu ErrorLog / ...