字典和集合
几种数据类型在内存中的访问方式
- 直接访问:数字
- 顺序访问:字符串 列表 元组
- 映射访问:字典
字典
dict
可下标类型(subscriptable) 可迭代类型(Iterable) 可变类型(mutable) 无序类型 一系列键值对 key-value 用冒号分割,格式如下:
pythond = {"key1": "value1", "key2": "value2"}
key 必须是不可变类型的数据(否则报错 unhashable)
value 可以是任意数据类型
如果 key 使用布尔值会被转换为 1 和 0解构赋值
pythond2 = {"key0": None, **d}
在 python3.6 以上版本中,字典默认按插入的顺序排列了键值对。
在 python3.8 以上版本中,字典可以使用 reversed()
按插入顺序反向迭代
索引
in 成员运算符
"key1" in d # 判断键是否存在 返回布尔值
getitem 操作
>>> d['key1']
'value1'
setitem 操作
d["key1"] = "debu"
有关的内置函数
len(dict)
返回键的数目
zip()
以拉链法惰性生成键值对:('a','b','c'),(1,2,3)
->[('a',1),('b',2)('c',3)]
dict()
以键值对生成字典:[('a',1),('b',2),('c',3)]
-> {'a':1,'b':2,'c':3}
;也可将有 keys 方法的可下标对象强制转换
常用方法
dict.fromkeys(可迭代对象,value)
静态方法生成字典,所有键的值都为 value
.copy()
浅拷贝
增删改查
.setdefault(key, value)
已存在则返回已存在的 value,不存在则设置。
.update(key=value)
.update(dict)
设置或覆盖,这里可对比之后章节函数的剩余参数。
.pop(key, None)
删除并返回其 value,不存在则返回第二个参数,第二个参数默认为 None。
.popitem()
随机删一个并返回其键值对。
.clear()
清空。
del d[key1]
删除一组键值对。
.get(key, None)
查找 不存在则返回第二个参数 默认为 None。
.items()
返回键值对组成的列表。功能与dict()
相反。
.keys()
返回键组成的列表,可下标对象转化为字典需要有这个方法。
.values()
返回值组成的列表。
字典合并
python3.9+
合并 (|
) 与更新 (|=
) 运算符。为现有的 {**d1, **d2}
和dict.update
字典合并方法提供了补充。
x = {"key1": "value1 from x", "key2": "value2 from x"}
y = {"key2": "value2 from y", "key3": "value3 from y"}
x | y
# {'key1': 'value1 from x', 'key2': 'value2 from y', 'key3': 'value3 from y'}
y | x
# {'key2': 'value2 from x', 'key3': 'value3 from y', 'key1': 'value1 from x'}
集合
set
可迭代类型(Iterable) 可变类型(mutable) 无序类型,元素不重复
生成方式:
{1,2,3,4,5}
set(可迭代对象)
规范的初始化
创建一个空字典或空集合的时候使用dict()
和set()
而不是使用{}
增删方法
s1.add(p_obj)
s1.update(s2)
s.claer() # 清空
s.pop() # 随机删除一个并返回其值
s.remove(value) # 删除 没有=>报错
s.discard(value) # 删除 没有不报错
浅拷贝
s.copy() # 如果是list直接使用切片就可以浅拷贝arr2=arr[:]
集合之间运算
运算 | 运算符表示 | 对象方法 |
---|---|---|
交集 | s1&s2 | s1.intersection(s2) |
并集 | s1|s2 | s1.union(s2) |
差集 | s1-s2 | s1.difference(s2) |
交叉补集 | s1.symmetric_difference(s2) |
s1.issubset(s2) # s1是否是s2子集
s1.issuperset(s2) # s1是否是s2超集
s1.intersection_update(s2)
s1.difference_update(s2)
s1.symmetric_difference_update(s2)
内置函数 set()
和 frozenset()
分别用来生成可变和不可变的集合
枚举类
enum 模块的枚举类包括
- Enum 枚举类
- IntEnum 值只能是 int 的枚举子类
- Flag 可参与和 Flag 的位运算且保持成员的枚举子类
- IntFlag 可参与和 int 的位运算且保持成员的枚举子类
创建
from enum import Enum
class Color(Enum):
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
枚举成员可以按值查找,属性访问或下标访问,可以 hash
>>> Color((0,0,255)) # 按值查找
<Color.BLUE: (0, 0, 255)>
>>> Color.RED # 属性访问
<Color.RED: (255, 0, 0)>
>>> Color['RED'] # 下标访问
<Color.RED: (255, 0, 0)>
拥有相同的值,后定义的成员是先定义的成员的别名,优先返回先定义的成员
@unique
枚举专用的类装饰器@enum.unique
。它不允许别名存在
from enum import Enum, unique
@unique
class Color(Enum):
AQUA = (0, 255, 255)
CYAN = (0, 255, 255)
# raise ValueError
# ValueError: duplicate values found in <enum 'Color'>: CYAN -> AQUA
__members__
映射了成员的有序字典
>>> for i in Color.__members__.items():
... print(i)
('RED', <Color.RED: (255, 0, 0)>)
('GREEN', <Color.GREEN: (0, 255, 0)>)
('BLUE', <Color.BLUE: (0, 0, 255)>)
拥有成员的枚举类不允许被继承。枚举类也不能实例化。
但是很自然地,枚举成员应该被当作实例来看待,无论是类型注解还是魔术方法。
格式化输出
使用.name
或.value
来输出
>>> Color.RED.name
'RED'
>>> Color.BLUE.value
(0, 0, 255)
配合魔术方法__repr__
和内置函数repr
来输出,成员就像实例一样。
class HTTP_method(Enum):
get = "GET"
post = "POST"
put = "PUT"
delete = "DELETE"
patch = "PATCH"
def __repr__(self):
return repr(self.value)
HTTP_method.get
# 'GET'