1
dict()
is slower than{}
list()
is slower than()
- 需要符号查找(不能预先知道
list()
有没有被重定义) - 方法调用
- 要检查有没有可迭代变量传入
2
特殊方法
__len__()
__getitem__()
__setitem__()
__iter__()
是为了被python解释器
调用的,自己不用调用它们,所以没有A.__len__()
方法,只有len(A)
3
自定义布尔值 -> 实现__bool__
4
__str__()
: readable, 面向用户__repr__()
: unambigous, 面向DEV
5
The Zen of Python
-
- 实用胜于纯粹
-
- 不能让特例特殊到开始破坏规则
6
内置序列类型
- 容器序列:任意类型,引用 -
list, tuple, deque
- 扁平序列:单一类型,值 -
str(3.0), byte(3.0), bytearray, memoryview
- 可变序列(MutableSequence):
list, deque
…- 不可变序列(Sequence):
tuple, str, byte
7
- list comprehension = listcomps 列表推导
- generator expression = genexps 生成器表达式
8
chr(65)
-> Aord(A)
-> 65unichr(12345)
-> u'\u3039'
9
列表推导的作用只有一个: 生成列表
10
genexps
优于listcomps
genexps
遵守了迭代器协议,可以逐个产生元素,而不是先建立一个完整的列表,避免了额外的内存占用
11
元组拆包
a,b = (a,b)
a,b = b,a
两个变量值交换
12
*
来处理剩下的元素
Python3: 平行赋值: a,b,*rest = range(5)
-> (0,1,[2,3,4])
13
namedtuple
和tuple
创建实例消耗内存一样,因为字段名都存在类里:
_fileds
类属性_make(iterable)
类方法_asdict()
实例方法
14
tuple
没有__reversed__
方法,但可以reversed(my_tuple)
15
切片赋值:改变list
中连续多个值
l = list(range(10))
l[2:5] = [20,30]
-> l:[0,1,20,30,5,6,7,8,9]
16
__iadd__
方法:就地加法
+
=__iadd__
*
=__imul__
17
id(object)
-> return “Identity(内存地址)” of an object
+=
or*=
用在list
上,不改变id+=
or*=
用在tuple
上,改变id,重新创建一个obj
18
如果一个方法对对象进行的是就地改动,那就应该返回None
19
list.sort
-> 就地改sorted()
-> 新建一个列表返回
Example:
sorted(fruits, key=len)
sorted(fruits, key=lower)
…
20
bisect
二分查找
bisect(haystack, needle)
insort(seq, item)
-> 插入后仍保持升序
21
字符串格式化
' '.format(a,b,c)
{0}
-> 位置参数{name}
-> 关键字参数{0[0]}
-> 对list
使用索引{0:*(填充字符)>(右对齐)10(宽度)}
-> 填充与格式化
22
array
场景->1000万个浮点数
deque
场景->需要频繁对序列进行FIFO
23
memoryview
24
numpy, scipy
25
collections.deque
:线程安全、快速从两端添加、删除元素。
场景:存放最近使用的几个元素
rotate(3)
:右边三个到左边。rotate(-4)
:左边四个到右边。
appendleft()
:单个。extend, extendleft
: 队列。
26
- **
散列表
**是字典
类型性能出众的根本原因。 collections.abc.Mapping
的instance- 原子不可变数据类型(
str, byte
和数值类型) - 散列值就是
id()
函数的返回值
27
字典创建方法
a = dict(one=1,two=2,three=3)
b = {'one':1,'two':2,'three':3}
c = dict(zip(['one','two','three'],[1,2,3]))
- 字典推导
dictcomp
28
**dict.setdefault
**处理不存在于dict
中的key
29
**collections.defaultdict
**是处理找不到key
的一个选择
dd = defautdict(list)
,如果'new-key'
不存在,dd['new-key']
会执行:
list()
建新列表
- 这个新列表作为
值
,new-key
为key
,放入dd
- 返回这个列表的引用
30
__missing__
只会被__getitem__
调用
31
如果要自定义一个映射类型,应该继承collections.UserDict
32
字典的变种
collections.OrderedDict
:popitem
方法 -> 删除并返回
collections.ChainMap
: 多个字典逐个查找
collections.Counter
:
ct = Counter('abracadabra')
- ->
Counter({'a':5,'b':2,'r':2,'c':1,'d':1})
UserDict
用户涌来继承写子类
TransformDict
33
不可变映射类型
types.MappingProxyType
:只读的映射视图
34
set
-> 许多唯一对象的聚集;frozenset
-> 不可变
集合
- 用于去重复:
list
->set
->list
- 合集,交集,差集 -> 场景:元素出现次数
如果是空集必须写成set()
35
散列表:稀疏数组(总有空白元素的数组)
key:value
-> 一个表元
因为所有表元大小一致,所以可以通过偏移量
来读取某个表元
用hash()
来计算散列值
36
存放数量巨大的记录用tuple
或namedtuple
dict
散列 -> 内存消耗大
37
dict
:空间换时间 -> 读取快 但 内存消耗大
Python解释器可能为字典扩容 -> 导致新建一个更大的散列表
38
集合 set
- 元素必须可散列
- 很耗内存
- 高效查找
- 次序取决于添加次序
- 添加元素可能改变已有元素次序(37中的扩容)
39
字符的最佳定义是Unicode
字符
Python3
从 str
对象中获取的元素是Unicode
字符
字符的具体表述取决于所用的编码
- 编码:码位 -> 字节序列
- 解码:字节序列 -> 码位(字符的标识)
40
字面量:双眼所见
41
utf_8
的别名:utf8
, u8
, utf-8
42
编码种类
latin1
(iso8859-1):是其他编码的基础cp1252
:Windows制定的latin1
的超集,添加了有用的符号gb2312
:用于编码简体中文的陈旧标准utf-8
:web最常见的8位编码,与ASCII
兼容
43
Python3 中默认使用 utf8
编码源码
44
判断编码
以下是肉眼方法
HTTP
和XML
,包含明确指明内容编码的首部
- 包含大于127的字节值,那么就不是ASCII
- 如果
b'\x00'
经常出现,那么就不是8位编码方案
统一字符编码侦测包:Chardet
45
Python中,函数是一等对象
- 运行时创建
- 能赋值给变量或数据结构中的元素
- 能作为参数传给函数
- 能被
return
46
__doc__
用于生成对象的帮助文本
47
函数式编程:特点之一是使用高阶函数
高阶函数:
- 接受函数作为参数
- 或
- 把函数作为结果返回
48
map, filter 和 reduce
在Python3中已经不是内置函数
被 listcomps
和 genexps
所替代(可读性原因)
49
匿名函数:lambda
50
使用callable()
函数来判断一个对象能否调用
51
用户定义可调用类型,只需实现实例方法__call__
52
函数内省
53
函数有但一般对象没有的特殊方法:
__annotations__
__call__
:实现()
运算符
54
函数注解只存放在__annotations__
属性里,Python不做检查、验证、强制…
注解只是元数据,可以供IDE、框架和装饰器工具使用
55
函数式编程
operator
->itemgetter
(get下标),attrgetter
(get name)
functools
内包含reduce
函数,partial
冻结参数,partialmethod
Example:
triple = partial(mul,3)
triple(7) -> 21
56
globals()
策略模式
57
命令模式:是回调机制的面向对象替代品
58
nonlocal
关键字。
装饰器 目的是增强函数
59
元编程 -> 在运行时改变程序的行为
装饰器的两大特性:
- 能把装饰的函数替换成其他函数
- 在加载模块时立即执行
60
装饰器 在被装饰的函数定义之后立即运行。通常是在导入时(加载模块时)
61
变量作用域规则
b = 6
def f2(a):
print(a)
print(b)
b = 9
f2(3)
输出 3
, local variable 'b' referenced before assignment
Python编译函数定义体时,它判断b
是局部变量,因为在函数中给它赋值了。生成的字节码证实了这种判断,Python会尝试从本地环境获取b
。后面调用f2(3)
时,f2
的定义体会获取并打印局部变量a
的值,但是尝试获取局部变量b
的值时,发现b
没有绑定值。
这不是缺陷,而是设计选择:Python不要求声明变量,但是假定在函数定义体中赋值的变量是局部变量。
如果在函数中赋值时想让解释器把b
当成全局变量,要使用global
声明。
62
闭包 不等同于 匿名函数
闭包是延伸了作用域的函数,函数是不是匿名的没有关系,关键是它能否访问定义体之外定义的非全局变量