Python Part1
知识点
- 对象三要素: id,type,value(地址)
- 栈:存放变量 ,堆:存放对象
- 变量无类型,对象有类型。
- 类型 | 规则
模块和包名 | 全小写
函数名 | 全小写
类名 | 首字母大写
常量名 | 全大写 - del 变量:删除变量之后对象还在,被python回收,清空内存。
- 三种进制:
- 0b或0B:二进制 01
- 0o或0O:八进制 01234567
- 0x或0X:十六进制 0123456789abcdef
- 同一运算符
is与==区别:is用于判断两个变量引用的对象是不是同一个,==用于判断两个变量引用对象的值是否相等。 - pyhon仅针对较小的整数缓存[-5,256]。如果保存为文件,则为[-5,∞]。上下界的原因:https://zhuanlan.zhihu.com/p/33907983
- 转义字符:
\ | 续行符
\ | 反斜杠符
’ | 单引号
" |双引号
\b | 退格
\n | 换行
\t | 横向制表符
\r | 回车 - 可变字符串 import io
- 位运算符:或|,异或^(相同为0,相异为1),与&
- 位运算: >> 右移相当于除以2,<<左移相当于乘2
- List.index(value,start,end)
- Reversed()返回迭代器
- 元组:不可改变,带有__next__()方法,访问和处理速度比列表快,元组可以作为dic的key,列表不行。
- 创建字典:
- {}, dict()
- dict(zip(k,v))
- dict.fromkeys(a:list)
- a.update(b) a,b都为dict 没有添加,有则覆盖
- 字典删除
- clear()删除所有键值对
- del(a[‘name’])删除元素
- b = a.pop(‘age’)删除元素并返回该key对应的value
- popitem()字典无序所以随机移除元素
- 字典核心底层逻辑:
字典对象的核心是散列表。散列表是一个稀疏数组,每个单元叫bucket,每个bucket有两部分,一是键对象的引用,一是值对象的引用。
比如: a[‘name’] = ‘Gaoqi’ 第一步先计算’name‘的散列值:hash(),第二步使用bin()转化为二进制编码之后按固定位数寻找,找到非空的位置即可放入键值对。
存的时候同理,bin(hash())依次固定位数取,找到非空位置后判断该位置的bin(hash(key))是否与所求相等。 - 字典总结
- 键必须可散列
- 数字,字符串,元组均可散列
- 自定义对象支持以下三点:
- 支持hash()
- 支持通过__eq__()方法检测相等性
- 若a == b为真,则hash(a) == hash(b)为真
- 字典在内存中开销巨大,空间换时间
- 键查询速度快
- 往字典里添加新键,可能导致扩容,导致散列表中键的次序变化。因此,不要在遍历字典的同时修改字典。
- 键必须可散列
- 集合底层实现就是字典,只有字典的键对象。集合相关操作:
- a|b 并集 a.union(b)
- a-b 差集 a.difference(b)
- a&b 交集 a.intersection(b)
- 循环代码优化:
- 减少循环内部不必要的计算
- 尽量减少内层循环的计算,尽可能向外提
- 局部变量查询较快,尽量使用局部变量
- 形参和实参。
- 形参:定义函数时使用,局部变量,属于函数
- 实参:调用函数时使用,传递给形参。
- 函数逻辑:
- def时在堆中就创建了一个函数对象
- 通过调用函数名找到函数对象
- test()等同于c = test c() 因为c复制了栈中的test,然后同样调用了该函数对象。
- 全局变量:
- 作用域为定义的模块,从头到尾。
- 一般避免使用,当作常量,GLOBAL声明。
- 局部变量:
- 函数中声明的变量。
- 若与全局变量同名,优先使用局部变量。
- 当函数被调用时,会创建栈帧(stackframe),栈帧存放局部变量,也会创建相关对象,调用完栈帧就被删除了。
- 参数传递本质上就是实参到形参的赋值操作,python中参数的传递都是“引用传递”,不是值传递。
- 传递可变对象,本质上是引用同一个对象。比如:
def f(m):
m.append(30)
f(b)
将b传给了m,创建栈帧,改变原可变对象,栈帧消失。
-
传递不可变对象,会在堆中创建一个新的对象,不可改变原对象。
-
shallow copy和deep copy(important)
浅拷贝不拷贝子对象的内容,只是拷贝子对象的引用。
深对象会连子对象的内存一起拷贝,对子对象的影响不会影响原对象。
浅拷贝:
深拷贝就是完全拷贝,不影响原对象。 -
传递不可变对象用浅拷贝。当不可变对象内包含可变子对象时,该可变子对象是可以被改变的。
-
可变参数:
- *param:将多个参数收集到一个元组对象中
- **param: 将多个参数收集到一个字典对象中
def f1(a,b,*c): print(a,b,c) def f2(a,b,**c): print(a,b,c) def f3(a,b,*c,**d): print(a,b,c,d) f1(2,8,3,7,8) -> 2,8,(3,7,8) f2(2,8,name='luis',age=18) -> 2,8,{name:luis,age:18} f3(2,8,3,6,7,name='luis',age=18) -> 2 8 (3, 6, 7) {'name': 'luis', 'age': 18}
-
lambda arg1,arg2: <表达式>
形参为arg1,arg2,表达式即函数体,返回值为计算结果。 -
eval函数将字符串当成有效表达式进行计算,参数:
- source:一个python表达式或者函数compile()返回的代码对象
- globals:可选,必须是字典对象
- locals:可选,映射任意对象
dict = {a=100,b=200} c = eval('a+b',dict) -> 300
-
递归函数:在栈内反复创建栈帧,先进后出后进先出(LIFO)。