python进阶(26)collections标准库
作者:互联网
namedtuple
namedtuple的由来
因为元组的局限性:不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义,所以引入namedtuple
这个工厂函数,来构造一个带字段名的元组。namedtuple
继承自tuple
类
命名元组赋予每个位置一个含义,提供可读性。它们可以用于任何普通元组,并添加了通过名字获取值的能力,通过索引值也是可以的。
namedtuple的格
highlighter- Pythoncollections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
typename
: 返回一个新的元组子类,名为typename。这个新的子类用于创建类元组的对象,可以通过字段名来获取属性值,同样也可以通过索引和迭代获取值。field_names
: 像['x', 'y'] 一样的字符串序列。另外field_names
可以是一个纯字符串,用空白或逗号分隔开元素名,比如 'x y' 或者 'x, y' 。rename=False
: 如果rename为true,无效字段名会自动转换成_+索引值
,比如 ['abc', 'def', 'ghi', 'abc'] 转换成 ['abc', '_1', 'ghi', '_3'] , 消除关键词def和重复字段名abc。default=None
: defaults 可以为 None 或者是一个默认值的 iterable 。default默认值赋值跟我们平常的默认值相反,default默认值是从最右边开始,比如field_names
中提供了3个字段['x', 'y', 'z']
,default默认值设置为(1, 2)
,那么我们必须为x指定1个值,y默认值为1,z默认值为2module=None
: 如果 module 值有定义,命名元组的 module 属性值就被设置。
namedtuple声明以及实例化
我们首先创建一个User类,定义3个字段name
、age
、height
,并给age设置默认值为18,给height设置了默认值18
User = namedtuple('User', ['name', 'age', 'height'], defaults=(18, 180)) print(User.__mro__)
我们查看结果
python
(<class '__main__.User'>, <class 'tuple'>, <class 'object'>)
可以看到我们声明的User类是继承于tuple
,接下来我们创建实例
user1 = User(name='jkc') user2 = User(name='jkc2', age=20, height=198) print(user1) print(user2) print(user1.name) print(user2.age)
运行结果为
pythonUser(name='jkc', age=18, height=180) User(name='jkc2', age=20, height=198) jkc 20
namedtuple的方法和属性
命名元组还支持三个额外的方法和两个属性。为了防止字段名冲突,方法和属性以下划线开始。_make(iterable)
类方法从存在的序列或迭代实例创建一个新实例。
>>> t = ['jkc3', 25, 190] >>> User._make(t) User(name='jkc3', age=25, height=190)
_asdict()
返回一个新的 dict ,它将字段名称映射到它们对应的值
>>> user4 = User(name='jkc4', age=28, height=200) >>> user4._asdict() {'name': 'jkc4', 'age': 28, 'height': 200}
_replace(**kwargs)
返回一个新的命名元组实例,并将指定域替换为新的值
>>> user5 = User(name='jkc5', age=30, height=210) >>> user5._replace(age=18) User(name='jkc5', age=30, height=210)
_fields
字符串元组列出了字段名。用于提醒和从现有元组创建一个新的命名元组类型
>>> user5._fields ('name', 'age', 'height')
_field_defaults
字典将字段名称映射到默认值。
>>> User._field_defaults {'name': 'jkc', 'age': 18, 'height': 180}
转换一个字典到命名元组,使用 ** 两星操作符
python>>> d = {'name': 'jkc6', 'age': 18, 'height': 180} >>> User(**d) User(name='jkc6', age=18, height=180)
OrderedDict
有序字典就像常规字典一样,但有一些与排序操作相关的额外功能。由于内置的 dict
类获得了记住插入顺序的能力(在 Python 3.7
中保证了这种新行为),它们变得不那么重要了。
与dict类的区别
- 常规的
dict
被设计为非常擅长映射操作。 跟踪插入顺序是次要的 OrderedDict
擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的。- 算法上,
OrderedDict
可以比dict
更好地处理频繁的重新排序操作。 这使其适用于跟踪最近的访问(例如在 LRU cache 中)。 - 对于
OrderedDict
,相等操作检查匹配顺序。 OrderedDict
类的popitem()
方法有不同的签名。它接受一个可选参数来指定弹出哪个元素。OrderedDict
类有一个move_to_end()
方法,可以有效地将元素移动到任一端。- Python 3.8之前, dict 缺少
__reversed__()
方法。