序列的修改、散列和切片
Vector第1版(不可切片版):
from array import array import reprlib import mathclass Vector:type_code = 'd'def __init__(self,components):self._components = array(self.type_code,components)def __iter__(self):return iter(self._components)def __repr__(self):components = reprlib.repr(self._components)components = components[components.find('['):-1]return 'Vector({})'.format(components)def __str__(self):return str(tuple(self))def __bytes__(self):return bytes([ord(self.type_code)]) + bytes(self._components)def __eq__(self, other):return tuple(self) == tuple(other)def __abs__(self):return math.sqrt(x*x for x in self._components)def __bool__(self):return bool(abs(self))@classmethoddef frombytes(cls,octets):t_code = chr(octets[0])comps = array(t_code)comps.frombytes(octets[1:])return cls(comps)longlist = [i for i in range(100)] longVector = Vector(longlist) print('repr(longVector):',repr(longVector))v = Vector([3.1,4.2]) print('str(v):',v) print('repr(v):',repr(v)) b = bytes(v) w = Vector.frombytes(b) print('repr(w):',repr(w)) print(v == w)输出: repr(longVector): Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...]) str(v): (3.1, 4.2) repr(v): Vector([3.1, 4.2]) repr(w): Vector([3.1, 4.2]) True
Vector第2版(不完美切片版):
from array import array import reprlib import mathclass Vector:type_code = 'd'def __init__(self,components):self._components = array(self.type_code,components)def __iter__(self):return iter(self._components)def __repr__(self):components = reprlib.repr(self._components)components = components[components.find('['):-1]return 'Vector({})'.format(components)def __str__(self):return str(tuple(self))def __bytes__(self):return bytes([ord(self.type_code)]) + bytes(self._components)def __eq__(self, other):return tuple(self) == tuple(other)def __abs__(self):return math.sqrt(x*x for x in self._components)def __bool__(self):return bool(abs(self))@classmethoddef frombytes(cls,octets):t_code = chr(octets[0])comps = array(t_code)comps.frombytes(octets[1:])return cls(comps)# 定义下面两个方法以后,Vector类就支持简单切片def __len__(self):return len(self._components)def __getitem__(self, idx):return self._components[idx]l = [i for i in range(100)] v = Vector(l) print('repr(longVector):',repr(v))# []操作符调用__getitem__ print(v[0],v[-1])# _components是一个array,所以切片返回array print(v[1:4])输出: repr(longVector): Vector([0.0, 1.0, 2.0, 3.0, 4.0, ...]) 0.0 99.0 array('d', [1.0, 2.0, 3.0])
切片原理
- 切片背后与slice对象和indices对象有关
- 实际调用的是slice(start, stop, stride).indices(len)
- 给定长度为len的序列,计算起始和结尾的索引,以及步幅。超出边界的索引会被截掉。
class MySeq:def __getitem__(self, item):return items = MySeq() l = [1,2,3,4,5]# 切片时传递给__getitem__的参数是slice对象 # 这里是slice(1, 4, None) print(s[1:4])# slice(1, 4, 2) print(s[1:4:2])# 在内置可迭代对象的__getitem__中,还要调用indices方法对start、stop、stride进行处理 # 步幅为正数,start=None自动替换成0 # stop超过len,自动替换成len # (0, 5, 2) print(slice(None, 10, 2).indices(5)) # 相应切片返回[1, 3, 5] print(l[:10:2])# 步幅=None,自动替换成1 # 步幅为正数,start=-3自动替换成len-3 # stop=None自动替换成len # (2, 5, 1) print(slice(-3, None, None).indices(5)) # 相应切片返回[3, 4, 5] print(l[-3::])# 步幅为负数,start=-3自动替换成len-3 # stop=None自动替换成-1 # (2, -1, -1) print(slice(-3, None, -1).indices(5)) # 相应切片返回[3, 2, 1] print(l[-3::-1])# 从2开始,倒退到3,切片为空 # (2, 3, -1) print(slice(-3, 3, -1).indices(5)) # 相应切片返回[] print(l[-3:3:-1])
Vector第3版(完美切片版):
from array import array import reprlib import math import numbersclass Vector:type_code = 'd'def __init__(self,components):self._components = array(self.type_code,components)def __iter__(self):return iter(self._components)def __repr__(self):components = reprlib.repr(self._components)components = components[components.find('['):-1]return 'Vector({})'.format(components)def __str__(self):return str(tuple(self))def __bytes__(self):return bytes([ord(self.type_code)]) + bytes(self._components)def __eq__(self, other):return tuple(self) == tuple(other)def __abs__(self):return math.sqrt(x*x for x in self._components)def __bool__(self):return bool(abs(self))@classmethoddef frombytes(cls,octets):t_code = chr(octets[0])comps = array(t_code)comps.frombytes(octets[1:])return cls(comps)# 定义下面两个方法以后,Vector类就支持简单切片def __len__(self):return len(self._components)def __getitem__(self, idx):cls = type(self)if isinstance(idx,slice):# 把slice对象传递给_components的__getitem__函数return cls(self._components[idx])elif isinstance(idx,numbers.Integral):# 直接返回相应元素return self._components[idx]else:msg = '{0} indices must be integers'raise TypeError(msg.format(cls.__name__))l = [i for i in range(100)] v = Vector(l) print('repr(longVector):',repr(v))# 传入整数,__getitem__返回相应元素 print(v[0],v[-1])# 经过改造后,切片返回Vector对象 print(repr(v[1:4]))
Vector第4版(带hash版):
from array import array import reprlib import math import numbers import functools import operatorclass Vector:type_code = 'd'def __init__(self,components):self._components = array(self.type_code,components)def __iter__(self):return iter(self._components)def __repr__(self):components = reprlib.repr(self._components)components = components[components.find('['):-1]return 'Vector({})'.format(components)def __str__(self):return str(tuple(self))def __bytes__(self):return bytes([ord(self.type_code)]) + bytes(self._components)def __eq__(self, other):# zip生成一个由元组构成的生成器,在Vector由大数据量的可迭代对象构成时,效率比较高# all函数在每一个元素都为True时返回Truereturn len(self)==len(other) and all(a==b for a,b in zip(self,other))def __hash__(self):# reduce接受三个参数,第一个参数是一个可接受两个参数的函数# 第二个参数是一个可迭代对象,第三个参数是初始值,如果可迭代对象为空,返回这个初始值hashes = (hash(i) for i in self)return functools.reduce(operator.xor, hashes, 0)def __abs__(self):return math.sqrt(x*x for x in self._components)def __bool__(self):return bool(abs(self))@classmethoddef frombytes(cls,octets):t_code = chr(octets[0])comps = array(t_code)comps.frombytes(octets[1:])return cls(comps)# 定义下面两个方法以后,Vector类就支持简单切片def __len__(self):return len(self._components)def __getitem__(self, idx):cls = type(self)if isinstance(idx,slice):# 把slice对象传递给_components的__getitem__函数return cls(self._components[idx])elif isinstance(idx,numbers.Integral):# 直接返回相应元素return self._components[idx]else:msg = '{0} indices must be integers'raise TypeError(msg.format(cls.__name__))shortcut = 'xyzt'# 动态存取属性def __getattr__(self, item):cls = type(self)if len(item) == 1:pos = cls.shortcut.find(item)if 0 <= pos < len(self._components):return self._components[pos]else:raise AttributeError('{0} has no attribute {1}'.format(cls,item))l = [3.1, 4.2] v = Vector(l) print('repr(v):',repr(v))print('v.x:',v.x)print('hash(v):',hash(v)) 输出:
repr(v): Vector([3.1, 4.2])
v.x: 3.1
hash(v): 384307168202284039
转载于:https://www.cnblogs.com/StackNeverOverFlow/p/10561741.html
序列的修改、散列和切片相关推荐
- 第10章 序列的修改、散列和切片
# <流畅的Python>读书笔记 # 第10章 序列的修改.散列和切片 转载于:https://www.cnblogs.com/larken/p/10576719.html
- Python学习之路29-序列的修改、散列和切片
<流畅的Python>笔记. 本篇是"面向对象惯用方法"的第三篇.本篇将以上一篇中的Vector2d为基础,定义多维向量Vector. 1. 前言 自定义Vector类 ...
- mysql 散列存储_什么是数据库散列存储? - 蚂蚁吞大象的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
什么是数据库散列存储? 上一篇 / 下一篇 2012-11-30 17:25:03 / 个人分类:数据库 (转载自百度空间http://hi.baidu.com/pplboy/item/2d7a26 ...
- 消息认证之SHA散列算法族
消息认证--安全散列算法SHA(Secure Hash Algorithm) 一. 消息认证 对要传递的消息进行加密有两个目的,其一是防止消息被消息发送者和消息接收者之外的第三者窃听(被动攻击),在之 ...
- python中的序列类型数据结构元素的切片操作_PythonI/O进阶学习笔记_4.自定义序列类(序列基类继承关系/可切片对象/推导式)...
前言: 本文代码基于python3 Content: 1.python中的序列类分类 2. python序列中abc基类继承关系 3. 由list的extend等方法来看序列类的一些特定方法 4. l ...
- 散列算法(也叫:摘要算法)
散列算法(也叫:摘要算法): 特点: ① 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的. ② 消息摘要看起来是"随机的".这些比特看上去是胡乱的杂凑在一起的. ③ 一般 ...
- 文本的DES加密 MD5散列值 DSA的数字签名
作者:未知 文本的DES加密 为了对称加密的安全,将密码进行封装,先新建一个用于保存密码的类库cl: using System; using System.Text ; namespace cl { ...
- 数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)...
2019独角兽企业重金招聘Python工程师标准>>> 数字签名是什么? 1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥. 2. 鲍勃把公钥送给他的朋友们----帕蒂.道格.苏珊-- ...
- 数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)
数字签名是什么? 1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥. 2. 鲍勃把公钥送给他的朋友们--帕蒂.道格.苏珊--每人一把. 3. 苏珊给鲍勃写信,写完后用鲍勃的公钥加密,达到保密的效果. 4 ...
最新文章
- CSS中浮动布局float(小米布局案例、导航栏案例、overflow)
- excel mysql实时交换数据_Excel与数据库的数据交互
- select报错 spark_spark-sql master on yarn 模式运行 select count(*) 报错日志
- arraylist线程安全吗_Java中的集合和线程安全
- PYTHON笔记 面向对象程序设计
- shell 命令 netstat 查看端口占用
- 智力问答选择题_2018智力问答题大全及答案:智力问答题大全及答案
- MVPArms学习笔记[待续]
- 唯心主义-柏拉图的哲学世界
- Bit Miracle Jpegv2.1.1117
- 使用jwt方式的接口访问
- 今天有空,不如来找找“双鸭山大学”的由来吧~
- 基于饥饿博弈搜索算法的函数寻优算法
- 如何删除复制文字产生的word回车换行符
- 怎样将好多个字符串组装成一个数组
- 如何成为一名优秀的后端工程师
- 寻找客户的“痛点”---离岸开发的新视点
- Mac安装mysql初始密码忘记 重新设置密码
- 蓝牙认证检测实验室授权政策与认可要求解析
- 四大CPU体系结构:ARM、X86/Atom、MIPS、PowerPC
热门文章
- 我的世界javamod怎么装_耐斯地板 | 木地板的铺装方向,你还不知道?
- python将图片转换为字符_python如何将图片转换为字符图片
- python科学计算库-python 科学计算基础库安装
- SQL Server高级查询之子查询(单行子查询)
- Gorgeous Sequence线段树区间跟新
- 博弈-巴什博弈-P/N图
- Unity3D基础36:场景自适应与场景切换
- bzoj 2281: [Sdoi2011]黑白棋 bzoj 4550: 小奇的博弈(Nimk博弈+DP)
- 改变灰度图像直方图的均值和标准差
- pytorch 中 torch.optim.Adam 方法的使用和参数的解释