【序列更新&散列&切片】
"""
from array import array
import reprlib
array1 = array('d',(1,2,3))
print(array1) #array('d', [1.0, 2.0, 3.0])
com = reprlib.repr(array1)
components = com[com.find('['):-1]
print('Vector({})'.format(components)) #Vector([1.0, 2.0, 3.0])
"""
#10.2 Vector类第一版,与Vector2d类兼容
#例子10-2
from array import array
import reprlib
import math
import numbers
import functools
import operator
import itertools class Vector:
typecode = 'd' def __init__(self,components):
self._components = array(self.typecode,components) # 把Vector分量保存在一个数组里 def __iter__(self):
return iter(self._components) #构造一个迭代器 def __repr__(self):
components = reprlib.repr(self._components) #使用reprlib.repr()获取self._components的有限长度表示形式(如array('d',[0.0,1.0,2.0,3.0,4.0,...]))
components = components[components.find('['):-1] #把字符串插入Vector的构造方法调用之前,去掉前面的array('d' 和后面的)
return 'Vector({})'.format(components)
'''
def __str__(self):
return str(tuple(self))
'''
__str__ = __repr__ def __bytes__(self):
return (bytes([ord(self.typecode)]) + bytes(self._components)) #直接用self._components构建bytes对象
def __eq__(self, other):
return tuple(self) == tuple(other)
def __abs__(self):
return math.sqrt(sum(x*x for x in self)) #不能直接用hypot方法了,因此我们先计算各分量的平方之和,然后再使用sqrt方法开平方
def __bool__(self):
return bool(abs(self))
@classmethod
def frombytes(cls,octets):
typecode = chr(octets[0])
memv = memoryview(octets[1:]).cast(typecode)
return cls(memv) #构造方法变了,所以不用像前面那样使用*拆包
def __len__(self): #以下两个方法实现切片的序列
return len(self._components)
def __getitem__(self, item):
cls = type(self) #获取实例的类,供后面使用
if isinstance(item,slice):
return cls(self._components[item])
elif isinstance(item,numbers.Integral):
return self._components[item]
else:
msg = '{cls.__name__} indices must be integers'
raise TypeError(msg.format(cls=cls))
def __eq__(self, other):
return len(self) == len(other) and all(a==b for a,b in zip(self,other)) #all函数,只要一次比较结果为False,则结果为False.所有结果为True,结果为True
#考虑到,按照老规则的话,Vector([1,2]) 和(1,2)的比较结果是一样的,所以出来了这个新规则
def __hash__(self):
hashes = map(hash,self._components)
return functools.reduce(operator.xor,hashes)
def angle(self,n):
r = math.sqrt(sum(x*x for x in self[n:]))
a = math.atan2(r,self[n-1])
if (n == len(self) -1) and (self[-1] < 0):
return math.pi*2 - a
else:
return a
def angles(self):
return (self.angle(n) for n in range(1,len(self)))
def __format__(self, fmt_spec):
if fmt_spec.endswith('h'):
fmt_spec = fmt_spec[:-1]
coords = itertools.chain([abs(self)],self.angles())
a = list(self.angles())
outer_fmt = '<{}>'
else:
coords = self
outer_fmt = '({})'
components = (format(c,fmt_spec) for c in coords)
return outer_fmt.format(','.join(components)) #通过@property来动态获取属性,想要获取向量的四个分量时,要写四个这样的特性,太麻烦,所以选择__getattr__这个特殊方法。
#属性查找失败后,解释器会调用__getattr__方法。简单来说,对my_obj.x表达式,python会检查my_obj实例有没有名为x的属性;如果没有,到类(my_obj.__class__)中查找;如果还没有,顺着继承树继续查找。如果依旧找不到,调用my_objh所属类中
#...定义的__getattr__方法,传入self和属性名称的字符串形式。
#例子10-8
shortcut_names = 'xyzt'
def __getattr__(self, item):
cls = type(self)
if len(item) == 1:
pos = cls.shortcut_names.find(item)
if 0<= pos < len(self._components):
return self._components[pos]
msg = '{.__name__!r} object has no attribute {!r}'
raise AttributeError(msg.format(cls,item)) #【备注】1⃣️使用reprlib.repr的方式需要做些说明。这个函数用于生成大型数据结构或递归结构的安全表现形式,它会限制输出字符串的长度,用'...'表示截断的部分。我希望Vector实例的表现形式是Vector([3.0,4.0])这样,而不是
#Vector(array('d',[3.0,4.0])),因为我们不需要实例中的实现细节。
#【备注】2⃣️编写__repr__方法时,本可以使用这个表达式生成简化的componets显示形式:reprlib.repr(list(self._components))。然而,这么做优点浪费,因为要把self._components中每个元素复制带一个列表中,
#然后使用列表的表示形式。
#【备注】3⃣️调用repr()目的是调试
#【备注】4⃣️我们本可以让Vector继承Vector2d,没这么做的原因幼儿。其一,两个构造方法不兼容,因此不建议继承。这一点可以通过适当处理__init__方法的参数解决,不过第二个原因更重要:我想把Vector类当作单独的事例,以此实现序列协议 #10.3 协议和鸭子类型 '''
#例子10-3 可切片的序列
v7 = Vector(range(7))
print(v7[-1]) #6.0
print(v7[1:4]) #Vector([1.0, 2.0, 3.0])
print(v7[-1:]) #Vector([6.0])
print(v7[1,2]) #TypeError: Vector indices must be integers Vector不支持多维索引 #例子10-4 了解__getitem__和切片的行为
class MySeq:
def __getitem__(self, item):
return item
s = MySeq()
print(s[1]) #1
print(s[1:4]) #slice(1, 4, None)
print(s[1:4:2]) #slice(1, 4, 2)
print(s[1:4:2,9]) #(slice(1, 4, 2), 9)
print(s[1:4:2,7:9]) #(slice(1, 4, 2), slice(7, 9, None))
#例子10-5 查看slice属性
print(slice) #<class 'slice'>
print(dir(slice))
print(slice(None,10,2).indices(5)) #(0, 5, 2)
print('ABCDE'[:10:2]) #ACE 根据上方的原理,等同于 'ABCDE'[0:5:2]
print(slice(-3,None,None).indices(5)) #(2, 5, 1)
print('ABCDE'[-3:]) #CDE 等同于'ABCDE'[2:5:1] #例子10-15 zip内置函数的使用
print(zip(range(3),'ABC')) #<zip object at 0x102832788>
print(list(zip(range(3),'ABC'))) #[(0, 'A'), (1, 'B'), (2, 'C')]
print(list(zip(range(3),'ABC',[0.0,1.1,2.2,3.3]))) #[(0, 'A', 0.0), (1, 'B', 1.1), (2, 'C', 2.2)] zip有个奇怪的特性,当一个可迭代对象耗尽后,它不发出警告就停止
from itertools import zip_longest
print(list(zip_longest(range(3),'ABC',[0.0,1.1,2.2,3.3],fillvalue=-1))) #[(0, 'A', 0.0), (1, 'B', 1.1), (2, 'C', 2.2), (-1, -1, 3.3)] print(','.join(format(c,'.3e') for c in (3.45678,0.555555))) #3.457e+00,5.556e-01
print('{:.3e},{:.3e}'.format(3.4567855,0.555555)) #3.457e+00,5.556e-01
import itertools
print(itertools.chain('123','456')) #<itertools.chain object at 0x10c554c18>
print(list(itertools.chain('123', '456'))) # ['1', '2', '3', '4', '5', '6']
print(list(itertools.chain([3.4444],(3.4444444,)))) #[3.4444, 3.4444444]
#tests of 'format()' with spherical coordinates in 2d,3d and 4d:
v3 = Vector([1,1])
print(format(v3,'h')) #<1.4142135623730951,0.7853981633974483>
print(format(v3,'.3eh')) #<1.414e+00,7.854e-01>
print(format(v3,'0.5fh')) #<1.41421,0.78540>
v4 = Vector([1,1,1])
print(format(v4,'h')) #<1.7320508075688772,0.9553166181245093,0.7853981633974483>
v5 = Vector([-1,-1,-1,-1])
print(format(v5,'.3eh')) #<2.000e+00,2.094e+00,2.186e+00,3.927e+00>
#tests of 'format()' with cartesian coordinates in 2d:
v5 = Vector([3,4])
print(format(v5)) #(3.0,4.0)
print(format(v5,'.2f')) #(3.00,4.00)
print(format(v5,'.3e')) #(3.000e+00,4.000e+00)
#tests of 'format()' with cartesian coordinates in 3d and 7d:
v6 = Vector([3,4,5])
print(format(v6))
v7 = Vector(range(7)) #(3.0,4.0,5.0)
print(format(v7)) #(0.0,1.0,2.0,3.0,4.0,5.0,6.0)
#tests of hashing
v9 = Vector([3,4])
v10 = Vector(range(6)) #7 1
print(hash(v9),hash(v10))
#Most hash values on ono-integers vary from a 32-bit to 64-bit CPython build::
import sys
v8 = Vector([3.1,4.2])
print(hash(v8)) #384307168202284039
print(hash(v8) == (384307168202284039 if sys.maxsize > 2**32 else 357915986)) #True
#tests of '.__bytes__ ' and 'frombytes()' methods:
v11 = Vector([3,4,5])
v11_clone = Vector.frombytes(bytes(v11))
print(v11_clone) #Vector([3.0, 4.0, 5.0])
print(v11 == v11_clone) #True # 例子10-9 针对例子10-8的验证,不恰当的行为:为v.x赋值没有报错,但是前后矛盾
v12 = Vector(range(5))
print(v12) #Vector([0.0, 1.0, 2.0, 3.0, 4.0])
print(v12.x) #0.0
v12.x = 10
print(v12.x) #10
print(v12) #为向量赋新值后,向量依然没变。Vector([0.0, 1.0, 2.0, 3.0, 4.0])
#【分析】如果向量的分量数组中没有新值,为什么v12.x返回10?例子10-9之所以前后矛盾,是__getattr__的运作方式导致的:仅当对象没有指定名称的属性时,python才会调用那个方法,这是一种后备机制。可是,像v12.x=10这样赋值
#...赋值后,v12对象就有x属性了,因此使用v12.xhuoqu x属性的值时不会调用__getattr__方法了,解释器直接返回绑定到v12.x上的值,即10。为避免这种前后矛盾的现象,我们要改写Vector中设置属性的逻辑。
#例子10-10 实现__setter__方法:虽然这个例子不支持为Vector分量赋值,但是有一个问题要特别注意:多数时候,如果实现了—__getattr__方法,那么也要实现__setattr__ 方法,以防对象的行为不一致。
#如果像允许修改分量,针对Vector可以使用__setitem__,支持v[0]=1.1,或者实现__setattr__,支持v.x=1.1。不过,我们要保持Vector是不可变的,因为接下去的实验我们要把它变成可散列的。
#这里格外讲一下__setattr__
class Test:
shortcut_names = 'xyzt'
def __setattr__(self, key, value):
cls = type(self)
if len(key) == 1:
if key in cls.shortcut_names:
error = 'readonly attribute {attr_name!r}'
elif key.islower():
error = "cannot set attribute 'a' to 'z' in {cls_name!r}"
else:
error = ''
if error:
msg = error.format(cls_name=cls,attr_name=key)
raise AttributeError(msg)
super().__setattr__(key,value)
v11 = Test()
#v11.x = 2 #AttributeError: readonly attribute 'x'
#v11.a = 3 #AttributeError: cannot set attribute 'a' to 'z' in <class '__main__.Test'>
v11.B = 3
print(v11.B) #3
#【分析】
#1⃣️ 为了给AttributeError选择错误信息,我查看了内置的complex类型的行为,因为complex对象是不可变的,而且有一堆数据属性:real imag。如果试图修改任何一个属性,complex实例会抛出AttributeError,而且把错误
#消息设置为"cannot set attribute'。而如果尝试为受保护的只读属性赋值,得到的错误消息是'readonly attribute'。在__setattr__方法中为error字符串选词时,我参考了这两个错误消息
#注意,我们没有禁止为全部属性赋值,只是禁止为单个小写字母属性赋值,以防与只读属性x y z t 混淆
#2⃣️ 我们知道,在类型声明__slots__属性可以防止设置新实例属性;因此,你可能想使用这个功能,而不像这里所做的,实现__setattr__方法。可是,不将以只为了避免创建实例属性而使用它。__slots__属性只应该用于节省内存,而且仅当内存严重不足时才使用
'''

【list&tuple&dict】

# 栗子 list排序


ls = ['d.txt','a.xlxs','a.xlas','b.txt']
print(ls) #['d.txt', 'a.xlxs', 'a.xlas', 'b.txt'] ls.sort(key=lambda x:x[0])
print(ls) #['a.xlxs', 'a.xlas', 'b.txt', 'd.txt'] ls.sort(key=lambda x:x[4])
print(ls) #['a.xlas', 'b.txt', 'd.txt', 'a.xlxs'] students = [('john','A',15),('jane','B',12),('dave','B',10)]
print(sorted(students,key=lambda s:s[2])) #[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
												

【Python】【数据类型】的更多相关文章

  1. python 数据类型---布尔型& 字符串

    python数据类型-----布尔型 真或假=>1或0 >>> 1==True True >>> 0==False True python 数据类型----- ...

  2. Python 数据类型及其用法

    本文总结一下Python中用到的各种数据类型,以及如何使用可以使得我们的代码变得简洁. 基本结构 我们首先要看的是几乎任何语言都具有的数据类型,包括字符串.整型.浮点型以及布尔类型.这些基本数据类型组 ...

  3. day01-day04总结- Python 数据类型及其用法

    Python 数据类型及其用法: 本文总结一下Python中用到的各种数据类型,以及如何使用可以使得我们的代码变得简洁. 基本结构 我们首先要看的是几乎任何语言都具有的数据类型,包括字符串.整型.浮点 ...

  4. Python数据类型及其方法详解

    Python数据类型及其方法详解 我们在学习编程语言的时候,都会遇到数据类型,这种看着很基础也不显眼的东西,却是很重要,本文介绍了python的数据类型,并就每种数据类型的方法作出了详细的描述,可供知 ...

  5. Python学习笔记(五)--Python数据类型-数字及字符串

    Python数据类型:123和'123'一样吗?>>> 123=='123'False>>> type(123)<type 'int'>>> ...

  6. python数据类型之元组、字典、集合

    python数据类型元组.字典.集合 元组 python的元组与列表类似,不同的是元组是不可变的数据类型.元组使用小括号,列表使用方括号.当元组里只有一个元素是必须要加逗号: >>> ...

  7. 1 Python数据类型--

    常见的Python数据类型: (1)数值类型:就是平时处理的数字(整数.浮点数) (2)序列类型:有一系列的对象并排或者排列的情况.如字符串(str),列表(list),元组(tuple)等 (3)集 ...

  8. Python数据类型和数据操作

    python数据类型有:int,float,string,boolean类型.其中string类型是不可变变量,用string定义的变量称为不可变变量,该变量的值不能修改. 下面介绍python中的l ...

  9. Python数据类型(python3)

    Python数据类型(python3) 基础数据类型 整型 <class 'int'> 带符号的,根据机器字长32位和64位表示的范围不相同,分别是: -2^31 - 2^31-1 和 - ...

  10. 二、Python数据类型(一)

    一.Python的基本输入与输出语句 (一)输出语句 print() 示例: print('你好,Python') print(4+5) a = 10 print(a) 输出的内容可以是字符串,变量, ...

随机推荐

  1. word 加载adobe acrobat ,保存word中的清晰图片

    1:先安装 adobe 并激活 https://blog.csdn.net/xintingandzhouyang/article/details/82558235 2:打开word,点击   文件&g ...

  2. spfa 判断负环 (转载)

    当然,对于Spfa判负环,实际上还有优化:就是把判断单个点的入队次数大于n改为:如果总的点入队次数大于所有点两倍 时有负环,或者单个点的入队次数大于sqrt(点数)有负环.这样时间复杂度就降了很多了. ...

  3. PAT 1068 Find More Coins[dp][难]

    1068 Find More Coins (30)(30 分) Eva loves to collect coins from all over the universe, including som ...

  4. 随机模拟MCMC和Gibbs Sampling

    随机模拟 统计模拟中有一个重要的问题就是给定一个概率分布 p(x),我们如何在计算机中生成它的样本.一般而言均匀分布 Uniform(0,1)的样本是相对容易生成的. 通过线性同余发生器可以生成伪随机 ...

  5. android开发中遇到的一些问题

    buildToolsVersion 设置buildtool版本 今天遇到一个奇怪问题instant not supported 原来是设置显示offline...这个很无语,adb devices又能 ...

  6. Shell篇(三)TC Shell

    Shell脚本的首行一般写为"#!+路径"来告诉系统,以路径所指定的程序来解释此脚本. 可以写为 #! /bin/tcsh -f (-f表示快速启动,不启动~/.tcshrc) S ...

  7. 解读jquery.filtertable.min

    jQuery.FilterTable是一款表格搜索过滤和单元格高亮插件. 该插件允许你对任意表格进行条件过滤,并且它会将搜索到的结果单元格高亮显示,非常实用和强大. 使用方法在页面中引入jquery和 ...

  8. FastReport问题整理(转)

    FastReport问题整理 博客分类: 软件开发   部分来自网上,部分来自网友,部分来自Demo如果有新的内容,会不断更新.. 更新历史: 2009-02-27 加入套打方案全攻略(原:jinzh ...

  9. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

  10. Python: 正则表达式匹配反斜杠 "\"

    Python正则表达式匹配反斜杠 "\" eg: >>>a='w\w\w' 'w\\w\\w' #  打印出来的 "\\" 被转义成 一个反斜 ...