一、协议是什么

1、协议(protocols)与其他编程语言中的接口很相似,它规定你那些方法必须要定义。然而在Python中协议就显的不那么正式,事实上,在Python中,协议更像是一种指南

2、容器类型的协议

** 如果你希望定制的容器是不可变的话,那你只需要定义__len__(),和__getitem__()方法

** 如果你希望定制的容器是可变的话,那你除了定义__len__() 和__getitem__()方法外,还需要定义__setitem__()和 __delitem__()两个方法

3、容器类型

__len__(self)          定义当被len()调用时的行为(返回容器中元素的个数)

__getitem__(self,key)      定义获取容器中指定元素的行为,相当于self[key]

__setitem__(self,key,value)    定义设置容器中指定元素的行为,相当于self[key] = value

__delitem__(self,key)      定义删除容器中指定元素的行为,相当于del self[key]

__item__(self)          定义当迭代容器中元素的行为

__reversed__(self)          定义当被reversed()调用时的行为

__contains__(self,item)       定义当使用成员测试运算符(in 或 not in)时的行为

魔法方法详解:https://fishc.com.cn/thread-48793-1-2.html

二、 编写一个不可改变的自定义列表,要求记录列表中每个元素被访问的次数

#定制一个不可改变的列表,并且记录每个元素的访问次数
class CountList:
def __init__(self,*args):#不知道需要传入多少个参数,那么就设置一个可变的参数集
self.values = [x for x in args]#列表推导式
#用列表推导式遍历用户传入的参数并建立一个列表
#self.value里面的内容是用户传入的参数
print("self_value++",self.values)
self.count = {}.fromkeys(range(len(self.values)),0)
#用fromey()方法建立一个字典,self.count是字典
#字典的key是self.value的索引,对应的value值分别初始化为0
print("self.count--",self.count) def __len__(self):
return len(self.values) #当len被调用时,返回了容器中元素的个数 def __getitem__(self,key):
#这里用户想要得到某个参数的访问次数,需要传入该参数的索引值
self.count[key] +=1 #每访问一次key对应的value就记录一次
return self.values[key] 执行结果:
>>> c1 = CountList(1,3,5,7,9)
self_value++ [1, 3, 5, 7, 9]
self.count-- {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
>>> c1[1]
3
>>> c1.count
{0: 0, 1: 1, 2: 0, 3: 0, 4: 0}
>>> c1[1]
3
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c1[1]
3
>>> c1.count
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0} '''
|-- 由打印出来的结果:
|-- self_value++ [1, 3, 5, 7, 9]
|-- self.count-- {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
|-- 可以得知,列表里面放的是传入的参数,只不过是已列表推导式形成一个列表,字典里面放的是列表的索引以及访问列表内属性的次数,默认为0
|-- 采用__len__():当len被调用时,返回了容器中元素的个数
|-- 为了实现每访问一次元素,就使访问的次数叠加1,必须传入字典self.count的key,并且逐步+1:self.count[key] +=1
'''

三、python中统计list中各元素出现的此时

1、利用python字典统计

2、利用python的collection中的Counter的类统计

3、利用python的panda包下的value_counts的类统计

#利用python字典统计
a = [1,2,3,1,2,5]
dict = {}
for key in a:
dict[key] = dict.get(key,0)+1 print(dict) 执行结果:
{1: 2, 2: 2, 3: 1, 5: 1
#利用python的collection中的Counter的类统计

from collections import Counter
a =[2,2,2,3,3,4,5]
result = Counter(a)
print(result) 执行结果:
Counter({2: 3, 3: 2, 4: 1, 5: 1})
#利用pandas包下的value_counts方法
import pandas as pd
a = [2,2,33,4,5,5]
result = pd.value_counts(a)
print(result) 执行结果:
5 2
2 2
4 1
33 1
dtype: int64
>>>
#panda包的value_counts()方法不仅可以统计list中元素出现的次数,还可以对矩阵元素进行统计
import pandas as pd
a = pd.DataFrame([[1,2,3],
[3,1,3],
[1,2,1]])
result = a.apply(pd.value_counts)
print(result) 执行结果:
0 1 2
1 2.0 1.0 1.0
2 NaN 2.0 NaN
3 1.0 NaN 2.0

四、读取数据库内的数据,并且统计数据库内某一列元素出现的次数(大约100w条数据)

from collections import Counter
import pandas as pd
import numpy
import time #随机生成一个含有一百万整数的列表
def get_random_list():
numpy.random.seed(10)
return numpy.random.randint(0,1000000,1000000) #第一种方法:字典
def get_list(l):
dict = {}
t1 = time.time()
for i in l:
if i in dict.keys(): #判断元素是否在字典内,如果在则对应的value+1
dict[i] = int(dict[i])+1
else:
dict[i] = 1 #如果不在,字典中新增对应的items t2 = time.time()
#print("list_dict==",dict)
print("list_time==",t2-t1) #第二种方法:采用list的count()函数:用于统计某个元素在列表内出现的次数
def get_count_py_count(l):
dict = {}
t1 = time.time()
s = set(l) #集合:得到不重复的元素 for i in s:
#解决:AttributeError: 'numpy.ndarray' object has no attribute 'count错误的方法:增加一个tolist()函数
dict[i] = l.tolist().count(i) #对集合中的每一个元素分别计数,存入dictionary中 t2 = time.time()
print("count_time:",t2-t1)
return dict '''
|-- 第三种方法:采用collections的Counter类
|-- Counter(l)统计列表内数字出现的次数,然后放入字典内:dict(count)
'''
def get_count_py_counter(l):
t1 = time.time()
count = Counter(l)
t2 = time.time()
print("counter_time++",t2-t1)
count_dict = dict(count)
return count_dict '''
|-- 第四种方法:采用pandas包的value_counts方法
|-- pd.value_counts(l)统计列表内数字出现的次数,然后放入字典内:dict(count)
'''
def get_count_py_pandas(l):
t1 = time.time()
count = pd.value_counts(l)
t2 = time.time()
print("pandas_time--",t2-t1)
count_dict = dict(count)
return count_dict if __name__ == "__main__":
l = get_random_list()
get_list(l)
#print("出现的次数:",l.tolist().count(355353))
#get_count_py_count(l)
get_count_py_counter(l)
get_count_py_pandas(l) 执行结果:
list_time== 1.8361890316009521
counter_time++ 0.8999738693237305
pandas_time-- 0.28310179710388184 '''
|-- 由字典统计次数时间,Counter统计时间和value_counts统计时间可以看出:100万数据,pandas的统计时间是最短的
'''

  

【Python047-魔法方法:定制序列】的更多相关文章

  1. python魔法方法-自定义序列

    自定义序列的相关魔法方法允许我们自己创建的类拥有序列的特性,让其使用起来就像 python 的内置序列(dict,tuple,list,string等). 如果要实现这个功能,就要遵循 python ...

  2. python魔法方法-自定义序列详解

    自定义序列的相关魔法方法允许我们自己创建的类拥有序列的特性,让其使用起来就像 python 的内置序列(dict,tuple,list,string等). 如果要实现这个功能,就要遵循 python ...

  3. python_魔法方法(五):描述符和定制序列

    描述符(property的原理) 描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性.那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__(). ...

  4. python:类4——魔法方法(定制序列、迭代)、生成器、推导式

    一.定制序列(容器类型) http://bbs.fishc.com/forum.php?mod=viewthread&tid=48793&extra=page%3D1%26filter ...

  5. 洗礼灵魂,修炼python(40)--面向对象编程(10)—定制魔法方法+time模块

    定制魔法方法 1.什么是定制魔法方法 首先定制是什么意思呢?其实就是自定义了,根据我们想要的要求来自定义.而在python中,其实那些所谓的内置函数,内置方法,内置属性之类的其实也是自定义出来的,不过 ...

  6. python魔法方法、构造函数、序列与映射、迭代器、生成器

    在Python中,所有以__双下划线包起来的方法,都统称为"魔术方法".比如我们接触最多的__init__,魔法方法也就是具有特殊功能的方法. 构造函数 构造函数不同于普通方法,将 ...

  7. 零基础学习python_魔法方法(41-48课)(迭代器)

    接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...

  8. Python学习笔记(七)——魔法方法

    1.构造和析造 魔法方法就是被双下划线包围的方法 __init__()方法 __init__方法默认没有参数,返回值为none.类实例化对象需有明确的初始化步骤要重写函数 >>> c ...

  9. 《Python基础教程(第二版)》学习笔记 -> 第九章 魔法方法、属性和迭代器

    准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here ...

随机推荐

  1. MySQL主从同步问题

    1,The replication receiver thread cannot start because the master has GTID_MODE = OFF and this serve ...

  2. LA 3890 Most Distant Point from the Sea(半平面交)

    Most Distant Point from the Sea [题目链接]Most Distant Point from the Sea [题目类型]半平面交 &题解: 蓝书279 二分答案 ...

  3. C# asp.net webapi下支持文件下载输出接口

    /// <summary>     /// 下载文件     /// </summary>     public class DownloadController : ApiC ...

  4. caffe训练模型中断的解决办法(利用solverstate)

    caffe训练过程中会生成.caffemodel和.solverstate文件,其中caffemodel为模型训练文件,可用于参数解析,solverstate为中间状态文件 当训练过程由于断电等因素中 ...

  5. HDU 1087 最长不下降子序列 LIS DP

    Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HDU. May ...

  6. 《大话设计模式》c++实现 抽象工厂模式

    为了更清晰地理解工厂方法模式,需要先引入两个概念: 产品等级结构 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机.海信电视机.TCL电视机,则抽象电视机与具体品牌的电视机之间 ...

  7. C# 实现生产者消费者队列

    开发过程中经常会碰到这样的场景:需要从一个地方获取一些数据,然后处理数据并将其保存在数据库中. 1 2 3 4 5 6 7 8 9 10 private void FetchData() {} pri ...

  8. python读取excel中单元格的内容返回的5种类型

    (1) 读取单个sheetname的内容. 此部分转自:https://www.cnblogs.com/xxiong1031/p/7069006.html python读取excel中单元格的内容返回 ...

  9. 即时通信系统中实现聊天消息加密,让通信更安全【低调赠送:C#开源即时通讯系统(支持广域网)——GGTalk4.5 最新源码】

    在即时通讯系统(IM)中,加密重要的通信消息,是一个常见的需求.尤其在一些政府部门的即时通信软件中(如税务系统),对即时聊天消息进行加密是非常重要的一个功能,因为谈话中可能会涉及到机密的数据.我在最新 ...

  10. tomcat 、NIO、netty 本质

    tomcat 基于 Socket,面向 web 浏览器的通信容器 nio 同步非阻塞的I/O模型 netty 通信框架,对 nio 的封装