Python附带⼀个模块,它包含许多容器数据类型,名字叫作collections。 我们将讨论的是:
namedtupleenum.Enum (包含在Python 3.4以上)
另外还有defaultdict、counter、deque很常用不在赘述。
1、namedtuple
⼀个元组是⼀个不可变的列表,你可以存储⼀个数据的序列,它和命名元组(namedtuples)⾮常像,但有⼏个关键的不同。 主要相似点是都不像列表,你不能修改元组中的数据。为了获取元组中的数据,你需要使⽤整数作为索引:
man = ('Ali', 30)
print(man[0])
## 输出: Ali
那namedtuples是什么呢?它把元组变成⼀个针对简单任务的容器。你不必使⽤整数索引来访问⼀个namedtuples的数据。你可以像字典(dict)⼀样访问namedtuples,但namedtuples是不可变的。
from collections import namedtuple
Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
print(perry)
## 输出: Animal(name='perry', age=31, type='cat')
print(perry.name)
## 输出: 'perry'
以上可以看到,可以⽤名字来访问namedtuple中的数据。⼀个命名元组(namedtuple)有两个必需的参数。它们是元组名称和字段名称。 在上⾯的例⼦中,我们的元组名称是Animal,字段名称是'name','age'和'type'。 你不必使⽤整数索引来访问⼀个命名元组,这让你的代码更易于维护。⽽且,namedtuple的每个实例没有对象字典,所以它们很轻量,与普通的元组⽐,并不需要更多的内存。这使得它们⽐字典更快。然⽽,要记住它是⼀个元组,属性值在namedtuple中是不可变的,所以下⾯的代码不能⼯作:
from collections import namedtuple
Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
perry.age = 42
## 输出:
## Traceback (most recent call last):
## File "", line 1, in
## AttributeError: can't set attribute
你应该使⽤命名元组来让代码⾃注释,它们向后兼容于普通的元组,这意味着你可以既使⽤整数索引,也可以使⽤名称来访问namedtuple:
from collections import namedtuple
Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
print(perry[0])
## 输出: perry
最后,你可以将⼀个命名元组转换为字典,⽅法如下:
from collections import namedtuple
Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="Perry", age=31, type="cat")
print(perry._asdict())
## 输出: OrderedDict([('name', 'Perry'), ('age', 31), ...
2、Enum
另⼀个有⽤的容器是枚举对象,它属于enum模块,存在于Python 3.4以上版本中。Enums(枚举类型)基本上是⼀种组织各种东 西的⽅式。 让我们回顾⼀下上⼀个'Animal'命名元组的例⼦。它有⼀个type字段,问题是,type是⼀个字符串。那么问题来了,万⼀程序员输⼊了Cat,因为他按到了Shift键,或者输⼊了'CAT',甚⾄'kitten'? 枚举可以帮助我们避免这个问题,通过不使⽤字符串。考虑以下这个例⼦:
from collections import namedtuple
from enum import Enum
class Species(Enum):
cat = 1
dog = 2
horse = 3
aardvark = 4
butterfly = 5
owl = 6
platypus = 7
dragon = 8
unicorn = 9
# 依次类推
Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="Perry", age=31, type=Species.cat)
drogon = Animal(name="Drogon", age=4, type=Species.dragon)
tom = Animal(name="Tom", age=75, type=Species.cat)
charlie = Animal(name="Charlie", age=2, type=Species.kitten)
现在,我们进⾏⼀些测试:
print(charlie.type == tom.type)
# True
print(charlie.type)
# <Species.cat: 1>
这样就没那么容易错误,我们必须更明确,⽽且我们应该只使⽤定义后的枚举类型。 有三种⽅法访问枚举数据,例如以下⽅法都可以获取到'cat'的值:
Species(1)Species['cat']Species.cat
摘自:《python进阶》