Python 中提供了基础的不可变数据结构元组tuple,对元组元素的访问需通过索引来完成,对此需要熟记每个下标对应的具体含义。如果元素数量一多,要记清楚这些东西就会比较麻烦了,于是就出现了命名元组namedtuple。
基本语法有如下三种:
a = collections.namedtuple("Point",["x","y"])
a = collections.namedtuple("Point","x y")
a = collections.namedtuple("Point","x,y")
这样就创建了一个叫做Point的命名元组类,它拥有两个属性x,y。
以上得到的变量 a 并不直接是一个元组对象,它只是一个类,如果要创建它的实例,则需要像创建类实例一样调用它:
b = a( x = 0, y = 1 )
这样就创建了实例 b ,他内容为 x = 0,y = 1。
通过collections.namedtuple创建的命名元组类,实际上是元组类的子类,因此命名元组也可以通过索引访问元素。
基本语法如下:
print(b[0])
print(b[1])
也可以通过属性访问。
基本语法如下:
print(b.x)
print(b.y)
如果需要修改元组的元素,需要调用成员函数_replace(),它会返回一个包含新值的新实例。
基本语法如下:
b = b._replace( x = 1 )
计数器是一个无序容器,用于记录各种值出现的次数。它采用 键-值对 的形式存储,要记录的值作为key,这个值出现的次数作为value,value值可正可负。
基本语法如下:
a = collections.Counter()
也可以从列表,元组,字典,字符串等可迭代对象创建。
如下:
a = collections.Counter(['a','b','c'])
a = collections.Counter(('a','b','c'))
a = collections.Counter({'a':1,'b':1,'c':1})
a = collections.Counter("abc")
最后,你也可以直接指定 键-值对,来创建计数器。
如下:
a = collections.Counter(a=1,b=1,c=1)
上面5条语句创建出来的计数器a都是相同的。
计数器是字典的子类,因此可以像使用字典那样访问计数器元素,不过与字典不同的是,当访问计数器中不存在的元素的时候,不会产生异常,而是返回0。
如下:
print(c['a'])
print(c.b)
print(c['d'])
print(c.e)
输出样例:
1
1
0
0
要改变计数器中某一元素的值,除了可以使用操作字典的方式:a.a = XXX外,计数器还提供了两个成员函数update和subtract。
update函数接受一个可迭代对象,然后将这个对象中各种值出现的次数加到计数器中;
subtract函数接受一个可迭代对象,然后从计数器中减去可迭代对象中各种值出现的次数。
如下:
a.d = 2
print(a.d)
a.update("d")
print(a.d)
a.subtract("dd")
print(a.d)
输出样例:
2
3
1
基本语法如下:
del( a["d"] )
其中:
del:方法名。
a:计数器的实例。
d:计数器中待删除的元素。
计数器还提供了一个获取出现次数最多的n个元素的成员函数most_common,它返回包含这些元素的列表
如下:
top1 = a.most_common(1)
print(top1)
top2 = a.most_common(2)
print(top2)
all = a.most_common()
print(all)
输出样例:
[(‘a’, 1)]
[(‘a’, 1), (‘b’, 1)]
[(‘a’, 1), (‘b’, 1), (‘c’, 1)]
注意:如果有多个元素的值相同,那么它们之间的顺序是不可确定的。如果括号内无参数,则返回计数器中所有元素。
双向队列是一种能在队列两端都进行入队、出队操作的数据结构,比普通的队列更加灵活也更加复杂。
就像计数器Counter,双向队列可以调用无参构造函数创建一个空队列,也可以使用可迭代对象创建,并初始化一个队列。
如下:
a = collections.deque()
a = collections.deque(['a','b','c'])
a = collections.deque(('a','b','c'))
a = collections.deque({'a':0,'b':1,'c':2})
a = collections.deque("abc")
注意:第一行语句创建的是一个空队列,从字典创建时,使用的是它的键,而不是值。
双向队列与列表类似,也有append和pop这两个成员函数,他们的作用分别是向队列的右边增加元素和从队列的右边删除并返回一个元素。
如下:
a.append('d')
a.pop()
向队列的右边增加元素 ‘ d ’ ,从队列的右边删除一个元素。
与append,pop相对应的,还有一组对队列左边进行操作的函数:appendleft,popleft,用法也与前面的一组类似。
如下:
a.appendleft('e')
a.popleft()
向队列的左边增加元素 ‘ e ’ ,从队列的左边删除一个元素。
双向队列还提供了一对操作:extend和extendleft,用于将一个可迭代对象的所有迭代值,依次加入到队列的右边或者左边。
如下:
b = collections.deque()
b.extend("123")
c = collections.deque()
c.extendleft("123")
其中:
队列b中的元素依次是 1,2,3;
队列c中的元素依次是 3,2,1。
有序字典和普通的字典基本上是相似的,只有一点不同,那就是有序字典中键值对的顺序会保留插入时的顺序。
有序字典的创建方法和普通的字典类似,不过由于多了保留顺序的功能,因此在使用可迭代对象创建有序字典时,可以对它先排个序,让创建出来的字典元素也是有序的。
基本语法如下:
a = [('a',1),('b',3),('c',2)]
b = collections.OrderedDict(sorted(a,key=lambda s:s[0]))
b = collections.OrderedDict(sorted(a,key=lambda s:s[1]))
其中:
key=lambda s:s[0]时按照字典中 键 的大小排序;
key=lambda s:s[1]时按照字典中 值 的大小排序。
这里使用的sorted函数,它返回对一个可迭代对象排序后的结果,如果可迭代对象的元素不能直接进行比较(比如元素是一个列表或元组等),则需要指定key函数。
这里使用lambda表达式lambda s:s[0]和lambda s:s[1],分别指定key为列表a中每个元素(元组类型)的第一个元素和第二个元素。
有序字典提供了一个move_to_end函数,这个函数可以将指定的键值对移动到最前面或者最后面。
基本语法如下:
b.move_to_end('b',last = False)
b.move_to_end('b',last = True)
其中:
last = False时键值为 ‘ b ’ 的元素移动到字典的最前面;
last = True时键值为 ‘ b ’ 的元素移动到字典的最后面。
默认字典的功能与字典基本相同,但在访问一个不存在的key时,默认字典会提供一个默认值,而不是引发异常。
默认字典的构造函数接受一个工厂函数default_factory作为参数,可以将一个类型名看做是一个工厂函数,比如list,tuple,str等。这个函数会在要生成默认值的时候无参调用,如果使用类型名作为工厂函数,则这个类型必须要有无参构造函数。如果不提供工厂函数,那么默认值的功能就失效了,此时默认字典与普通dict表现的功能一致。
如下:
a = collections.defaultdict(int)
print(a['a'])
a = collections.defaultdict(tuple)
print(a['a'])
输出样例:
0
()