Python collections模块中的几种数据结构
namedtuple
-
namedtuple
是一种类似于元组的数据类型,除了tuple
的一些用法之外,还能更方便地通过属性名来访问数据
In[1]: from collections import namedtuple
In[2]: Person = namedtuple('Person', ['name', 'age', 'phone'])
In[3]: me = Person(name='me', age='1', phone=123465)
In[4]: me
Out[4]: Person(name='me', age='1', phone=123465)
从上面的例子中可以看出,当使用 nametuple
通过属性访问数据时,能让我们的代码更好维护(与索引相比)
def fun1():
...
return code, message
code, message = fun1()
Result = namedtuple('Recult', ['code', 'success'])
def fun2():
...
return Result(code=0, message='success')
result = func2()
从上面两种函数的返回方式来看,第二种的可读性是比第一种好的,尤其是当一次返回多个数据,又不想将返回结果封装成一个 class
的时候,可以使用 nametuple
-
不可变
- 与
tuple
类似,namedtuple的属性是不可变的
In[5]: me.age += 1 Traceback (most recent call last): File "/home/liujinxuan/Virtualenv/venv/local/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2878, in run_code exec(code_obj, self.user_global_ns, self.user_ns) File "<ipython-input-6-99c261b82013>", line 1, in <module> me.age += 1 TypeError: cannot concatenate 'str' and 'int' objects
- 与
更多用法,参考 https://docs.python.org/2/library/collections.html#collections.namedtuple
deque
-
deque
对象类似于list列表,不过你可以操作它的“两端”, 是一个高效实现插入和删除操作的双向列表,适合用于队列和栈In[1]: from collections import deque In[2]: q = deque() In[3]: q.append(0) In[4]: q.append(1) In[5]: q Out[5]: deque([0, 1]) In[6]: q.appendleft(2) In[7]: q Out[7]: deque([2, 0, 1]) In[8]: q.pop() Out[8]: 1 In[9]: q.popleft() Out[9]: 2
-
我们可以从任一端扩展这个队列中的数据:
In[10]: d.extendleft([d.extend([6,7,8])]) Out[10]: deque([6, 7, 8, 0])
-
我们也可以设置
deque
的大小,当元素数量超出设定的限制时,数据会从另一端被pop
出去In[11]: d = deque(maxlen=5) In[11]: d.extend([6, 7, 8, 0]) In [12]: d Out[13]: deque([6, 7, 8, 0, 1]) In [14]: d.append(2) In [15]: d Out[15]: deque([7, 8, 0, 1, 2]) In [16]: d.appendleft(6) In [17]: d Out[17]: deque([6, 7, 8, 0, 1])
更多用法, 参考 https://docs.python.org/2/library/collections.html#collections.deque
defaultdict
defaultdict
的用法与dict
类似, 不同的是, 当访问defaultdict
中不存在的值时,会返回一个默认值,而不是向dict
引发KeyError异常-
defaultdict
类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值:In [1]: from collections import defaultdict In [2]: d = defaultdict(list) In [3]: d['not_exist_key'] Out[3]: [] In [4]: def init_value(): ...: return 0 ...: In [5]: d = defaultdict(init_value) In [6]: d['not_exist_key'] Out[6]: 0
-
这种形式的默认值只有在通过
dict[key]
或者dict.__getitem__(key)
访问的时候才有效>>> from collections import defaultdict >>> print defaultdict.__missing__.__doc__ __missing__(key) # Called by __getitem__ for missing key; pseudo-code: if self.default_factory is None: raise KeyError((key,)) self[key] = value = self.default_factory() return value
defaultdict
实现了__missing__
方法,__missing__
方法的作用是当使用__getitem__()
方法访问一个不存在的键时(dict[key]
这种形式实际上是__getitem__()
方法的简化形式),会调用__missing__()
方法获取默认值,并将该键添加到字典中去。 更多用法参考 https://docs.python.org/2/library/collections.html#collections.defaultdict
Counter
- Counter是一个简单的计数器,帮助我们针对某项数据进行计数。
In [1]: from collections import Counter In [2]: s = '''HangZhou lukou''' In [3]: c = Counter(s) In [4]: c Out[4]: Counter({' ': 1, 'H': 1, 'Z': 1, 'a': 1, 'g': 1, 'h': 1, 'k': 1, 'l': 1, 'n': 1, 'o': 2, 'u': 3}) In [5]: c.most_common(5) # 出现次数最多的 5个字符 Out[5]: [('u', 3), ('o', 2), ('a', 1), (' ', 1), ('g', 1)]
- 更多用法参考 https://docs.python.org/2/library/collections.html#collections.Counter
OrderedDict
- Python中的
dict
是通过计算key
的哈希值来确定存储位置的,因此存在dict
中的数据是无序的,当我们需要获得一个有序的字典对象时,可以使用OrderedDict
,OrderedDict
中的数据会按照插入的顺序排序In [1]: from collections import OrderedDict In [2]: od = OrderedDict() In [3]: od['b'] = 1 In [4]: od['a'] = 1 In [5]: od['c'] = 1 In [6]: od Out[6]: OrderedDict([('b', 1), ('a', 1), ('c', 1)])
- 如果某个key对应的值改变了,顺序不变。
In [7]: od['a'] = 2 In [8]: od Out[8]: OrderedDict([('b', 1), ('a', 2), ('c', 1)])
- 在比较两个OrderDict时,OrderedDict要内容和顺序完全相同才会视为相等。
- 更多用法参考 https://docs.python.org/2/library/collections.html#collections.OrderedDict