collection是Python内建的一个实用工具包,提供一些使用的容器,用于对传统容器类型进行功能提升。
1. 简介
上面就是简介,不会扯了,贴两个链接好了。
Collections - 廖雪峰的Python教程
Collections - High-performance container datatypes - Python Doc
2. namedtuple
2.1 功能简介
namedtuple
为一个函数,用于产生一个tuple类的子类。由该类实例化后的对象可以像tuple一样pack/unpack,也可以通过预先定义好的成员名称访问对象内部的数据。例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| >>> from collections import namedtuple >>> Point = namedtuple("Point", ['x', 'y']) >>> Point <class '__main__.Point'> >>> Point.__base__ <type 'tuple'> >>> Point(x=1, y=2) Point(x=1, y=2) >>> Point(1,2) Point(x=1, y=2) >>> p = Point(1, 2) >>> p.x 1 >>> x, y = p >>> x 1 >>> Point._make((1,2)) Point(x=1, y=2)
|
2.2 成员函数
somenamedtuple._make(iterable)
, 将一个可迭代对象(list, tuple等)转化为一个namedtuple对象。
1 2 3
| >>> t = [11, 22] >>> Point._make(t) Point(x=11, y=22)
|
somenamedtuple._asdict()
, 将对象转化一个为键值和数据对应的OrderedDict.
1 2
| >>> p._asdict() OrderedDict([('x', 11), ('y', 22)])
|
somenamedtuple._replace(kwargs)
, 返回一个新对象,该对象中的值按照_replace函数中的参数所改变。
1 2 3
| >>> p = Point(x=11, y=22) >>> p._replace(x=33) Point(x=33, y=22)
|
somenamedtuple._fields
, 返回一个所有键值构成的dict.
1 2 3 4 5 6 7
| >>> p._fields ('x', 'y')
>>> Color = namedtuple('Color', 'red green blue') >>> Pixel = namedtuple('Pixel', Point._fields + Color._fields) >>> Pixel(11, 22, 128, 255, 0) Pixel(x=11, y=22, red=128, green=255, blue=0)
|
2.3 应用场景
列举一个应用场景:在进行sql查询时,cur.fetchone()
会返回一个tuple而不是dict,我们可以定义一个namedtuple, 然后将sql的查询数据转为namedtuple类,然后通过成员函数访问。举个栗子(私货):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Account = namedtuple("Account", ["username", "password"]) ... cur = self.db.cursor() cur.execute("SELECT username, password FROM account\ WHERE valid=1\ ORDER BY RANDOM()\ LIMIT 1") account= Account._make(cur.fetchone()) self.postdata["username"] = account.username self.postdata["password"] = account.password ...
self.login(account) ...
|
3. deque - 双端队列
3.1 介绍
deque为Double-Ended Queue的简写,用于提供一个可以快速进行两端的插入或删除操作的队列,同时可以像list一样通过下标访问数据。由于list是储存在线性空间的,其插入/删除数据的时间复杂度为O(n),所以当list比较长的时候,在其头部插入/删除数据的操作需要耗费大量时间。所以如果需要对list对象进行大量头和尾的插入删除操作时,使用deque会使程序的运行效率更高(当然,使用Queue模块的Queue和LifoQueue也是不错的选择)。需要注意的是,deque对象不支持在中间位置的插入操作。
deque对象也被包含在Queue模块中。
3.2 成员函数
append(x)
, appendleft(x)
, 在deque的尾/头插入对象x, 与list类似;
extend(iterable)
, extendleft(iterable)
, 与list的extend类似;
pop(x)
, popleft(x)
, 与list的pop类似;
clear()
, 清空deque的所有元素;
count(x)
, 统计deque中x元素的个数;
remove(x)
, 删除deque中的x元素,若x元素不存在,则触发ValueError;
reverse()
, 将deque反转,返回None, 与list的reverse类似;
rotate(i)
, 将deque最末尾i个元素取出并插入头部,若i<0, 则将头部|i|个元素取出添加到尾部。
4. Counter - 计数器
4.1 介绍
Counter类是dict的子类,提供一个计数器,可对hashable的对象进行计数。需要注意的是,对象的计数可以小于0.
4.2 基本操作
直接上例子:
1 2 3 4 5 6 7 8 9 10
| >>> c = Counter() >>> c = Counter('gallahad') >>> c = Counter({'red': 4, 'blue': 2}) >>> c = Counter(cats=4, dogs=8) >>> c Counter({'dogs': 8, 'cats': 4}) >>> c["dogs"] 8 >>> c["elephants"] 0
|
4.3 成员函数
elements()
, 返回一个迭代器,包含Counter中的所有元素,若元素x的计数为n,则x在迭代器中会出现n次。
1 2 3
| c = Counter(a=4, b=2, c=0, d=-2) >>> list(c.elements()) ['a', 'a', 'a', 'a', 'b', 'b']
|
most_common([n])
, 返回计数最多的n个元素。
1 2
| >>> Counter('abracadabra').most_common(3) [('a', 5), ('r', 2), ('b', 2)]
|
update([iterable-or-mapping])
, 在现有计数上添加参数所对应的计数。
1 2 3 4 5 6
| >>> c = Counter("1233") >>> c Counter({'3': 2, '1': 1, '2': 1}) >>> c.update("2345") >>> c Counter({'3': 3, '2': 2, '1': 1, '5': 1, '4': 1})
|
substact([iterable-or-mapping])
, 在现有计数上减去参数所对应的计数。
可以用在Counter对象上的通用函数和常见用法有:
sum(c.values())
, 所有计数之和
c.clear()
, 将计数重置
list(c)
, 返回所有元素构成的列表, 其中元素不会重复
set(c)
, 转化为set
dict(c)
, 转化为dict
c.items()
, 转化为由(元素, 计数)构成的列表
Counter(dict(list_of_pairs))
, 从上述列表转化为Counter对象
c.most_common()[:-n-1:-1]
, 出现最少的n个元素
c += Counter()
, 移除所有元素计数为0的元素
注意: 将某元素的计数赋值为0, 并不能在计数器的元素列表中删除该元素。若要删除该元素,需要用del
.
1 2 3 4 5 6 7 8 9 10 11 12 13
| >>> c = Counter("12") >>> c Counter({'1': 1, '2': 1}) >>> c["0"] 0 >>> c Counter({'1': 1, '2': 1}) >>> c["0"] = 0 >>> c Counter({'1': 1, '2': 1, '0': 0}) >>> del c["0"] >>> c Counter({'1': 1, '2': 1})
|
5. defaultdict
5.1 介绍
defaultdict类是dict类的子类,包含dict类的所有功能。与dict不同的是,在调用不存在的键值时,dict会抛出KeyError
异常,而defaultdict会执行__missing__
函数, 通过调用该函数来进行操作或返回值。
定义方式如下:
1 2 3 4
| d = defaultdict() a = defaultdict(lambda: "N/A")
print a["0"]
|
5.2 应用场景
1 2 3 4 5 6 7
| >>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] >>> d = defaultdict(list) >>> for k, v in s: ... d[k].append(v) ... >>> d.items() [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
|
6. OrderdDict
6.1 简介
使用dict
时,Key是无序的。在对dict
做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict
.
OrderedDict
的键值顺序按照键值被插入的顺序排列,而不是Key本身的顺序。
OrderdDict
的键值可以通过调用popitem
函数被弹出,弹出时弹出(key, item)的键值对。
1 2 3 4 5 6 7 8 9 10 11
| >>> a = OrderedDict({"one": 1}) >>> a["zero"] = 0 >>> a["two"] = 2 >>> a OrderedDict([('one', 1), ('zero', 0), ('two', 2)]) >>> a.popitem() ('two', 2) >>> a.popitem(last=False) ('one', 1) >>> a OrderedDict([('zero', 0)])
|
7. 参考文档
- 8.3 collections — High-performance container datatypes
- collections - 廖雪峰的官方教程
8. 后记
这篇博文写了两天,感觉在翻译文档,有点枯燥。一直觉得应该多去了解Python的内置常用模块,不要求完全熟练,至少要有个印象,这样在开发中需要使用这些模块的时候,才能够想起来用它。
所以,又填完一个坑。下一个应该是unittest吧。