流畅的python学习笔记
第一章节 python特殊方法
python里面的特殊方法(魔术方法)
__getitem__
,len()
collections.namedtuple构建一个简单的类,这个类只有少量的属性没有方法
def namedtuple(typename, field_names, verbose=False, rename=False)
typename:类名称
field_names:字段名称,保证元素间顺序不变的可遍历对象或者是逗号链接起来的字符串
verbose:设置为true的话会打印出类的定义代码
for i in x: 实际上调用的是iter(x),
x.__iter__()
方法__repr_
将对象用字符串的形式表达出来,交互式控制台和调试程序用repr函数来获取字符串表示__repr__
和__str__
的区别:str函数或者print打印一个对象的时候调用,如果没用实现str函数,python会使用repr调用,repr式用来记录日志,后者式用来给终端用户看的if (一个对象)或者while(一个对象)会调用这个对象的bool魔术方法,如果这个魔术方法没用定义它会len方法,返回0就是false,否则就会返回true
len的方法在内置类中调用特别块,因为它使用了cpython直接从C结构体中读取对象的长度,完全不会调用任何方法,
第二章节 序列
2.1 列表的分类
序列分为两种:
容器序列:list、tuple、collections.deque可以存放不同类型的数据,存放的是对象的引用
扁平序列:
str、bytes、bytearray、memoryview和array.array都只能容纳一种类型,存放的不是引用,是值。
可变的序列: list、bytearray、array.array、collections.deque和memoryview
不可变的:tuple、str和bytes。
2.2 列表的推导和可读性(生成列表)
2.3 生成器表达式
生成器表达式可以逐个的产出元素,而不是建立一个完整的列表,方括号换成圆括号。
2.4 元组
不可变的列表+记录
b,a=a,b交换变量
divmod(20,8)=(2,4)
元组的拆包
具名元组:collections.namedtuple的使用
2.5 切片
2.5.1 为什么切片最后一个值不取?
元组列表和字符串都支持切片操作。python的切片和区间操作不包含区间范围的最后一个元素是python的风格,
切片忽略最后一个元素的好处:
- 当只有末尾的数字的index的时候可以快速看出切片和区间里含有几个元素
- 当起止位置信息都可见的时候,可以快速计算出切片和区间的长度,
- 快速将序列分割成不重叠的两部分,my_list[:x]和my_list[x:]可以
2.5.2 切片的间隔取值
s[a,b,c]其中c为负值就是反向取值
seq.getitem(slice(start,stop,step))`
slice对象
2.5.3 多维切片和省略
2.5.4 序列使用+和*
不会修改原来的操作对象,构建一个全新的序列。
2.5.5 序列的增量赋值
+=使用的特殊方法是'__iadd__
,如果没实现就会调用__add__
不可变使用就会重新创建。可变数组会改变数组的值
These Python Tutor ,很好可视化代码的工具
dis.dis查看字节码,可以看到代码背后的运行机制。
2.5.6 list.sort和sorted的区别
sort不会返回值,它直接会就地进行一个排序,函数存在两个参数 key和reverse
2.5.7 bisect和insort进行已排序的序列的管理
2.5.9 deque
第三章 字典和集合
isinstance(my_dict,abc.Mapping),可散列需要有两个方法:__hash_`
和qe`,
字典推导
1.常见的映射方法
dict、collections.defaultdict、defaultdict.orderedDict
2.使用setdefault处理找不到的键
dict.setdefault(key, default=None)
setdefault 同时也会改变 dict 的值
3.映射的弹性键查询
4.字典的变种
collections.OrdereDict
子类化UserDict
5.集合
集合推导
6.字典中的散列表
散列表是一个稀疏数组,大概三分之一的空间是空的
内置的hash用于所有的内置类型的对象,且如果两个对象在比较的时候是相等的,那它们的散列值必须是相等的,否则散列表就不能正常的运行。如1==1.0返回true,那么hash(1)==hash(1.0)必须为真。
散列表算法:
获取my_dict[search_key]背后值,python首先会调用hash(search_key)来计算search_key的散列值,
7.字典的实现及其导致的结果
键必须是可散列的,可散列指的是:
- 支持hash()函数,通过
__hash_()
方法所得到的散列值是不变的 - 支持
__eq__()
方法检测相等性 - 若a==b为真,则hash(a)==hash(b)也为真。
字典的劣势:
字典在内存上的开销比较大,可以用具名元祖来代替字典。__slots_
可以改变实例属性的存储方式,由dict变成tuple.
键的次序取决于添加顺序
字典添加新建可能改变已有键的顺序
8.集合的实现以及导致的结果
散列表存放的是元素的引用。
集合里面的元素必须是可散列的,集合很消耗内存,可以很高效的判断元素是否是存在于集合
元素的次序取决于被添加到集合里的次序
往集合里面添加元素,可能会改变集合里已有元素的次序