如何全面掌握 Python Collection 模块的使用方法?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2258个文字,预计阅读时间需要10分钟。
Collections 模块简介Collections 模块是 Python 标准库中的一个重要部分,它提供了一些非常有用的数据结构,可以帮助我们更高效地处理数据。这个模块实现了特定目标的容器,以提供 Python 标准容器的替代品,并帮助解决各种实际问题。
Collections 模块
本文将简单介绍一个 Python 模块 Collections 。这个模块实现了一些很好用的数据结构,可以帮助我们解决不同的实际问题。
这个模块实现了特定目标的容器,以提供Python标准内建容器dict,list,set, 和tuple的替代选择。
namedtuple()
创建命名元组子类的工厂函数
deque
类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
ChainMap
类似字典(dict)的容器类,将多个映射集合到一个视图里面
Counter
字典的子类,提供了可哈希对象的计数功能
OrderedDict
字典的子类,保存了他们被添加的顺序
defaultdict
字典的子类,提供了一个工厂函数,为字典查询提供一个默认值
UserDict
封装了字典对象,简化了字典子类化
UserList
封装了列表对象,简化了列表子类化
UserString
封装了字符串对象,简化了字符串子类化
引入方法
import collections可以通过import collections导入该模块的方法,现在我们进入 ipython3 然后使用dir(collections)查看collections下都有哪些可以用的类。
In [1]: import collectionsIn [2]: dir(collections)
Out[2]:
['ChainMap',
'Counter',
'OrderedDict',
'UserDict',
'UserList',
'UserString',
'_Link',
'_OrderedDictItemsView',
'_OrderedDictKeysView',
'_OrderedDictValuesView',
'__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__getattr__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_chain',
'_collections_abc',
'_count_elements',
'_eq',
'_heapq',
'_iskeyword',
'_itemgetter',
'_nt_itemgetters',
'_proxy',
'_recursive_repr',
'_repeat',
'_starmap',
'_sys',
'abc',
'defaultdict',
'deque',
'namedtuple']
根据官方文档: 这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。
Counter
Counter是一个dict子类,可帮助计算可哈希对象的值。在其中,元素存储为字典的键,值可以为零或负值。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。 Counter 类有点像其他语言中的 bags或multisets。
在下例中,我们可以找到文件单词出现的次数:
from collections import Countersentence = "I can because i think i can"
# Counter是一个简单的计数器,可以数组中统计字符出现的个数:
counts = Counter(sentence.split())
print(counts) # Counter({'can': 2, 'i': 2, 'I': 1, 'because': 1, 'think': 1})
Counter对象有一个elements的方法,该方法在元素上返回迭代次数超过元素计数的迭代器。元素以任意顺序返回。
In [7]: c = Counter(a=4, b=2, c=0, d=-2)In [8]: list(c.elements())
Out[8]: ['a', 'a', 'a', 'a', 'b', 'b']
most_common是一种返回最常见元素及其计数(从最常见到最小)的方法。
In [9]: Counter('this is a test sentence').most_common(3)Out[9]: [('t', 4), ('s', 4), (' ', 4)]
Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0,而不是弹出一个KeyError:
>>> c = Counter(['eggs', 'ham'])>>> c['bacon'] # count of a missing element is zero
0
设置一个计数为0不会从计数器中移去一个元素。使用del来删除它:
>>> c['sausage'] = 0 # counter entry with a zero count>>> del c['sausage'] # del actually removes the entry
defaultdict
defaultdict是类似于字典的对象,它提供字典提供的所有方法,但将第一个参数(default_factory)作为字典的默认数据类型。使用defaultdict比使用dict.set_default方法执行相同操作更快。
>>> from collections import defaultdict>>> 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()
dict_items([('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])])
在该示例中,即使defaultdict对象中没有键,您也可以看到它会自动创建一个空列表。list.append然后有助于将值附加到列表中。
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
>>> from collections import defaultdict>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
nametuple
命名元组有助于了解元组中每个位置的含义,并允许我们以更好的可读性和自记录代码进行编码。您可以在使用元组的任何地方使用它们。在示例中,我们将创建一个命名元组以显示点的保留信息。
>>> from collections import namedtuple>>> Point = namedtuple('Point', ['x', 'y']) # Defining the namedtuple
>>> p = Point(10, y=20) # Creating an object
>>> p
Point(x=10, y=20)
>>> p.x + p.y
30
>>> p[0] + p[1] # Accessing the values in normal way
30
>>> x, y = p # Unpacking the tuple
>>> x
10
>>> y
20
deque
deque就是我们数据结构中听说的双端队列,Python已经帮我实现了这个功能。
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
>>> from collections import deque>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
# -*- coding: utf-8 -*-"""
下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
的加载动画
"""
import sys
import time
from collections import deque
fancy_loading = deque('>--------------------')
while True:
print('\r%s' % ''.join(fancy_loading))
fancy_loading.rotate(1)
sys.stdout.flush()
time.sleep(0.08)
# Result:
# 一个无尽循环的跑马灯
# ------------->-------
OrderedDict
顾名思义,有序字典。当我们使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持 Key 的顺序,可以用 OrderedDict:
>>> from collections import OrderedDict>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']
ChainMap
3.3 新版功能.
一个 ChainMap 类是为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理。它通常比创建一个新字典和多次调用 update() 要快很多。
ChainMap可以把一组dict串起来并组成一个逻辑上的dict。ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
一个 ChainMap 通过引用合并底层映射。 所以,如果一个底层映射更新了,这些更改会反映到 ChainMap 。
支持所有常用字典方法。另外还有一个 maps 属性(attribute),一个创建子上下文的方法(method), 一个存取它们首个映射的属性(property):
>>> baseline = {'music': 'bach', 'art': 'rembrandt'}>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
>>> list(ChainMap(adjustments, baseline))
['music', 'art', 'opera']
什么时候使用ChainMap最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。
总结
- Counter: 计数器,主要用来计数
- defaultdict: 带有默认值的字典
- namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
- deque: 双端队列,可以快速的从另外一侧追加和推出对象
- OrderedDict: 有序字典
- ChainMap:多个映射快速的链接到一起
站在巨人的肩膀上:
本文共计2258个文字,预计阅读时间需要10分钟。
Collections 模块简介Collections 模块是 Python 标准库中的一个重要部分,它提供了一些非常有用的数据结构,可以帮助我们更高效地处理数据。这个模块实现了特定目标的容器,以提供 Python 标准容器的替代品,并帮助解决各种实际问题。
Collections 模块
本文将简单介绍一个 Python 模块 Collections 。这个模块实现了一些很好用的数据结构,可以帮助我们解决不同的实际问题。
这个模块实现了特定目标的容器,以提供Python标准内建容器dict,list,set, 和tuple的替代选择。
namedtuple()
创建命名元组子类的工厂函数
deque
类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
ChainMap
类似字典(dict)的容器类,将多个映射集合到一个视图里面
Counter
字典的子类,提供了可哈希对象的计数功能
OrderedDict
字典的子类,保存了他们被添加的顺序
defaultdict
字典的子类,提供了一个工厂函数,为字典查询提供一个默认值
UserDict
封装了字典对象,简化了字典子类化
UserList
封装了列表对象,简化了列表子类化
UserString
封装了字符串对象,简化了字符串子类化
引入方法
import collections可以通过import collections导入该模块的方法,现在我们进入 ipython3 然后使用dir(collections)查看collections下都有哪些可以用的类。
In [1]: import collectionsIn [2]: dir(collections)
Out[2]:
['ChainMap',
'Counter',
'OrderedDict',
'UserDict',
'UserList',
'UserString',
'_Link',
'_OrderedDictItemsView',
'_OrderedDictKeysView',
'_OrderedDictValuesView',
'__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__getattr__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_chain',
'_collections_abc',
'_count_elements',
'_eq',
'_heapq',
'_iskeyword',
'_itemgetter',
'_nt_itemgetters',
'_proxy',
'_recursive_repr',
'_repeat',
'_starmap',
'_sys',
'abc',
'defaultdict',
'deque',
'namedtuple']
根据官方文档: 这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。
Counter
Counter是一个dict子类,可帮助计算可哈希对象的值。在其中,元素存储为字典的键,值可以为零或负值。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数。 Counter 类有点像其他语言中的 bags或multisets。
在下例中,我们可以找到文件单词出现的次数:
from collections import Countersentence = "I can because i think i can"
# Counter是一个简单的计数器,可以数组中统计字符出现的个数:
counts = Counter(sentence.split())
print(counts) # Counter({'can': 2, 'i': 2, 'I': 1, 'because': 1, 'think': 1})
Counter对象有一个elements的方法,该方法在元素上返回迭代次数超过元素计数的迭代器。元素以任意顺序返回。
In [7]: c = Counter(a=4, b=2, c=0, d=-2)In [8]: list(c.elements())
Out[8]: ['a', 'a', 'a', 'a', 'b', 'b']
most_common是一种返回最常见元素及其计数(从最常见到最小)的方法。
In [9]: Counter('this is a test sentence').most_common(3)Out[9]: [('t', 4), ('s', 4), (' ', 4)]
Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0,而不是弹出一个KeyError:
>>> c = Counter(['eggs', 'ham'])>>> c['bacon'] # count of a missing element is zero
0
设置一个计数为0不会从计数器中移去一个元素。使用del来删除它:
>>> c['sausage'] = 0 # counter entry with a zero count>>> del c['sausage'] # del actually removes the entry
defaultdict
defaultdict是类似于字典的对象,它提供字典提供的所有方法,但将第一个参数(default_factory)作为字典的默认数据类型。使用defaultdict比使用dict.set_default方法执行相同操作更快。
>>> from collections import defaultdict>>> 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()
dict_items([('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])])
在该示例中,即使defaultdict对象中没有键,您也可以看到它会自动创建一个空列表。list.append然后有助于将值附加到列表中。
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
>>> from collections import defaultdict>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
nametuple
命名元组有助于了解元组中每个位置的含义,并允许我们以更好的可读性和自记录代码进行编码。您可以在使用元组的任何地方使用它们。在示例中,我们将创建一个命名元组以显示点的保留信息。
>>> from collections import namedtuple>>> Point = namedtuple('Point', ['x', 'y']) # Defining the namedtuple
>>> p = Point(10, y=20) # Creating an object
>>> p
Point(x=10, y=20)
>>> p.x + p.y
30
>>> p[0] + p[1] # Accessing the values in normal way
30
>>> x, y = p # Unpacking the tuple
>>> x
10
>>> y
20
deque
deque就是我们数据结构中听说的双端队列,Python已经帮我实现了这个功能。
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
>>> from collections import deque>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
# -*- coding: utf-8 -*-"""
下面这个是一个有趣的例子,主要使用了deque的rotate方法来实现了一个无限循环
的加载动画
"""
import sys
import time
from collections import deque
fancy_loading = deque('>--------------------')
while True:
print('\r%s' % ''.join(fancy_loading))
fancy_loading.rotate(1)
sys.stdout.flush()
time.sleep(0.08)
# Result:
# 一个无尽循环的跑马灯
# ------------->-------
OrderedDict
顾名思义,有序字典。当我们使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持 Key 的顺序,可以用 OrderedDict:
>>> from collections import OrderedDict>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']
ChainMap
3.3 新版功能.
一个 ChainMap 类是为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理。它通常比创建一个新字典和多次调用 update() 要快很多。
ChainMap可以把一组dict串起来并组成一个逻辑上的dict。ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
一个 ChainMap 通过引用合并底层映射。 所以,如果一个底层映射更新了,这些更改会反映到 ChainMap 。
支持所有常用字典方法。另外还有一个 maps 属性(attribute),一个创建子上下文的方法(method), 一个存取它们首个映射的属性(property):
>>> baseline = {'music': 'bach', 'art': 'rembrandt'}>>> adjustments = {'art': 'van gogh', 'opera': 'carmen'}
>>> list(ChainMap(adjustments, baseline))
['music', 'art', 'opera']
什么时候使用ChainMap最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数。
总结
- Counter: 计数器,主要用来计数
- defaultdict: 带有默认值的字典
- namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
- deque: 双端队列,可以快速的从另外一侧追加和推出对象
- OrderedDict: 有序字典
- ChainMap:多个映射快速的链接到一起
站在巨人的肩膀上:

