主题
Python数据类型
字符串
str.isnumeric()
和 str.isdigit()
的区别:
返回结果 | isnumeric | isdigit |
---|---|---|
True | Unicode数字、全角数字(双字节)、 罗马数字、汉字数字(如"四五伍玖"等) | Unicode数字、全角数字(双字节)、 罗马数字、byte数字(单字节) |
False | 带符号数字(如"-1"等) | 汉字数字,带符号数字 |
Error | byte数字(单字节) |
扩展容器
扩展容器包括一些常见的数据结构和对基础容器的扩展,了解使用场景即可,属于锦上添花的内容。collections 中比较常用的有:
collections | 名称 | 描述 |
---|---|---|
namedtuple | 命名元组 | 给元组的每个值取一个名字,通过名字来访问值,增强代码可读性。 |
deque | 双端队列 | 两端插入或删除元素比 list 更快,时间复杂度为O(1),并且可以设置队列的最大长度。 |
defaultdict | 默认字典 | 为字典的键提供默认值。 |
Counter | 计数器 | 可以方便快速地计数,获取计数最多的前N个等。 |
ChainMap | 链式映射 | 将多个字典合并为一个字典处理。通常比创建一个字典再update更快。 |
ChainMap例子:
console
>>> from collections import ChainMap
>>> a = {"x": 1, "z": 3}
>>> b = {"y": 2, "z": 4}
>>> c = ChainMap(a, b)
>>> c["x"]
1
>>> c["z"]
3
>>> c.maps
[{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]
>>> c1 = c.new_child()
>>> c1.maps # 本质是一个列表按顺序存放了多有的字典
[{}, {'x': 1, 'z': 3}, {'y': 2, 'z': 4}]
>>> c1['x']
1
>>> c1.parents
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
>>> c1['x'] = 2 # 增删改只针对第一个字典
>>> c1
ChainMap({'x': 2}, {'x': 1, 'z': 3}, {'y': 2, 'z': 4})
>>> a['x'] = 3
>>> c1 # 引用对象,修改a会影响c
ChainMap({'x': 2}, {'x': 3, 'z': 3}, {'y': 2, 'z': 4})
>>> del c1['z'] # 第一个字典没有 z,所以会 KeyError
ChainMap总结:内部 maps 属性保留了所有字典,增删改都只针对第一个字典,搜索会按顺序遍历所有字典直到找到第一个键。
可变对象与不可变对象
- 不可变对象可以哈希,能作为字典的键;而可变对象则不能被哈希。
- 通常情况下类的实例对象是可以被哈希的,但如果修改类的
__hash__ = None
,那么实例对象就不能被哈希了。 - 可变对象作为函数参数传入,传递的是对象的引用,修改引用会直接修改原对象;不可变对象作为函数参数传递的是值,修改值不会影响原对象。
不可变对象 | 可变对象 | |
---|---|---|
赋值运算符 | 没有新的内存地址,都指向同一块内存空间 | 没有新的内存地址,是原对象的引用。修改会影响对方。 |
浅拷贝 | 有新的内存地址,但子元素是复制原对象子元素的引用。所以修改内部的可变对象会影响原对象 | |
深拷贝 | 有新的内存地址,不可变子元素复制引用(内存地址相同),可变子元素创建新副本(内存地址不同) |
不可变对象:
python
a = 10
b = a
b = 20 # 重新赋值
需要注意:虽然b是a的引用,但对于不可变对象,重新给引用赋值,原对象是不会修改的。
可变对象:
python
from copy import copy,deepcopy
a = [1000, 200, [1, 2]]
b = a # 赋值
b = copy(a) # 浅拷贝
b = deepcopy(a) # 深拷贝

提示
列表的操作符[:]
和list.copy
方法都属于浅拷贝。