python基础collections的使用

Posted sysu_lluozh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础collections的使用相关的知识,希望对你有一定的参考价值。

Python的数据类型有list, tuple, dict, str等,collections是实现特定目标的容器,以提供Python标准内建容器dict , list , set和tuple的替代选择

  • Counter
    字典的子类,提供了可哈希对象的计数功能
  • OrderedDict
    字典的子类,保留了他们被添加的顺序
  • defaultdict
    字典的子类,提供了一个工厂函数,为字典查询提供了默认值
  • namedtuple
    创建命名元组子类的工厂函数
  • deque
    类似列表容器,实现了在两端快速添加(append)和弹出(pop)

Counter

Counter是一个简单的计数器,可用于统计字符串、列表等的元素个数

栗子

>>> from collections import Counter
>>>
>>> s = 'aaaabbbccd'
>>> c = Counter(s)        # 创建了一个 Counter 对象
>>> c                     
Counter('a': 4, 'b': 3, 'c': 2, 'd': 1)
>>> isinstance(c, dict)   # c 其实也是一个字典对象
True
>>> c.get('a')
4
>>> c.most_common(2)      # 获取出现次数最多的前两个元素
[('a', 4), ('b', 3)]

常用方法

  • elements()
    返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略
  • most_common([n])
    返回一个列表,提供n个访问频率最高的元素和计数
  • subtract([iterable-or-mapping])
    从迭代对象中减去元素,输入输出可以是0或者负数
  • update([iterable-or-mapping])
    从迭代对象计数元素或者从另一个 映射对象(或计数器)添加
>>> c = collections.Counter('hello world hello lucy'.split())
>>> c
Counter('hello': 2, 'world': 1, 'lucy': 1)
>>> # 获取指定对象的访问次数,也可以使用get方法
... c['hello']
2
>>> # 查看元素
... list(c.elements())
['hello', 'hello', 'world', 'lucy']
>>> c1 = collections.Counter('hello world'.split())
>>> c2 = collections.Counter('hello lucy'.split())
>>> c1
Counter('hello': 1, 'world': 1)
>>> c2
Counter('hello': 1, 'lucy': 1)
>>> # 追加对象,+或者c1.update(c2)
... c1+c2
Counter('hello': 2, 'world': 1, 'lucy': 1)
>>> # 减少对象,-或者c1.subtract(c2)
... c1-c2
Counter('world': 1)
>>> # 清除
... c.clear()
>>> c
Counter()

OrderedDict

Python的dict是无序的,不受添加的顺序的控制

>>> dict([('a', 10), ('b', 20), ('c', 15)])
'a': 10, 'c': 15, 'b': 20

collections.OrderedDict 类提供了保留添加顺序的字典对象

>>> from collections import OrderedDict
>>> o = collections.OrderedDict()
>>> o['k1'] = 'v1'
>>> o['k3'] = 'v3'
>>> o['k2'] = 'v2'
>>> o
OrderedDict([('k1', 'v1'), ('k3', 'v3'), ('k2', 'v2')])

如果在已经存在的key上添加新的值,将会保留原来的key的位置,然后覆盖value值

>>> o['k1'] = 666
>>> o
OrderedDict([('k1', 666), ('k3', 'v3'), ('k2', 'v2')])
>>> dict(o)
'k1': 666, 'k3': 'v3', 'k2': 'v2'

defaultdict

在Python中使用dict时,如果访问了不存在的key,会抛出KeyError异常,因此,在访问之前经常需要对key作判断,比如:

>>> d = dict()
>>> s = 'aaabbc'
>>> for char in s:
...     if char in d:
...         d[char] += 1
...     else:
...         d[char] = 1
...
>>> d
'a': 3, 'c': 1, 'b': 2

使用defaultdict,可以给字典中的key提供一个默认值。访问defaultdict中的key,如果key存在,就返回key对应的value,如果key不存在,就返回默认值

>>> from collections import defaultdict
>>> d = defaultdict(int)   # 默认的 value 值是 0
>>> s = 'aaabbc'
>>> for char in s:
...     d[char] += 1
...
>>> d
defaultdict(<type 'int'>, 'a': 3, 'c': 1, 'b': 2)
>>> d.get('a')
3
>>> d['z']
0

使用defaultdict时,可以传入一个工厂方法来指定默认值

  • 使用int作为default_factory
>>> fruit = collections.defaultdict(int)
>>> fruit['apple'] = 2
>>> fruit
defaultdict(<class 'int'>, 'apple': 2)
>>> fruit['banana']  # 没有对象时,返回0
0
>>> fruit
defaultdict(<class 'int'>, 'apple': 2, 'banana': 0)
  • 使用list作为default_factory
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = collections.defaultdict(list)
>>> for k,v in s:
...     d[k].append(v)
...
>>> d
defaultdict(<class 'list'>, 'yellow': [1, 3], 'blue': [2, 4], 'red': [1])
>>> d.items()
dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
  • 使用dict作为default_factory
>>> nums = collections.defaultdict(dict)
>>> nums[1] = 'one':1
>>> nums
defaultdict(<class 'dict'>, 1: 'one': 1)
>>> nums[2]

>>> nums
defaultdict(<class 'dict'>, 1: 'one': 1, 2: )
  • 使用set作为default_factory
>>> types = collections.defaultdict(set)
>>> types['手机'].add('华为')
>>> types['手机'].add('小米')
>>> types['显示器'].add('AOC')
>>> types
defaultdict(<class 'set'>, '手机': '华为', '小米', '显示器': 'AOC')

namedtuple

经常用tuple(元组)来表示一个不可变对象,比如用一个(姓名, 学号, 年龄)的元组来表示一个学生:

>>> stu = ('ethan', '001', 20)
>>> stu[0]
'ethan'

这里使用tuple没什么问题,但可读性比较差,必须清楚索引代表的含义,比如索引0表示姓名,索引1表示学号。如果用类来定义,就可以通过设置属性name, id, age来表示,但就有些小题大作

可以通过 namedtuple 为元组的每个索引设置名称,然后通过属性名来访问

三种定义命名元组的方法
第一个参数是命名元组的构造器(如下的:Person1,Person2,Person3)

>>> P1 = collections.namedtuple('Person1',['name','age','height'])
>>> P2 = collections.namedtuple('Person2','name,age,height')
>>> P3 = collections.namedtuple('Person3','name age height')

实例化命名元组

>>> lucy = P1('lucy',23,180)
>>> lucy
Person1(name='lucy', age=23, height=180)
>>> jack = P2('jack',20,190)
>>> jack
Person2(name='jack', age=20, height=190)
>>> lucy.name  # 直接通过 实例名.属性 来调用
'lucy'
>>> lucy.age
23

deque

deque是双端队列,允许在队列两端添加或删除元素
collections.deque返回一个新的双向队列对象,从左到右初始化(用方法append()),从iterable(迭代对象)数据创建。如果iterable没有指定,新队列为空

collections.deque队列支持线程安全,对于从两端添加(append)或者弹出(pop),复杂度O(1)

常用方法

  • append(x):添加x到右端
  • appendleft(x):添加x到左端
  • clear():清除所有元素,长度变为0
  • copy():创建一份浅拷贝
  • count(x):计算队列中个数等于x的元素
  • extend(iterable):在队列右侧添加iterable中的元素
  • extendleft(iterable):在队列左侧添加iterable中的元素
    注:在左侧添加时,iterable参数的顺序将会反过来添加
  • index(x[,start[,stop]]):返回第 x 个元素(从 start 开始计算,在stop之前)。返回第一个匹配,如果没找到的话,抛出ValueError
  • insert(i,x):在位置i插入x
    注:如果插入会导致一个限长deque超出长度 maxlen 的话,就抛出一个IndexError
  • pop():移除最右侧的元素
  • popleft():移除最左侧的元素
  • remove(value):移去找到的第一个value,没有抛出ValueError
  • reverse():将deque逆序排列,返回 None
  • maxlen:队列的最大长度,没有限定则为None
>>> from collections import deque

>>> q = deque(['a', 'b', 'c', 'd'])
>>> q.append('e')         # 添加到尾部
>>> q
deque(['a', 'b', 'c', 'd', 'e'])
>>> q.appendleft('o')     # 添加到头部
>>> q
deque(['o', 'a', 'b', 'c', 'd', 'e'])
>>> q.pop()               # 从尾部弹出元素
'e'
>>> q
deque(['o', 'a', 'b', 'c', 'd'])
>>> q.popleft()           # 从头部弹出元素
'o'
>>> q
deque(['a', 'b', 'c', 'd'])
>>> q.extend('ef')        # 在尾部 extend 元素
>>> q
deque(['a', 'b', 'c', 'd', 'e', 'f'])
>>> q.extendleft('uv')    # 在头部 extend 元素,注意顺序
>>> q
deque(['v', 'u', 'a', 'b', 'c', 'd', 'e', 'f'])
>>>
>>> q.rotate(2)           # 将尾部的两个元素移动到头部
>>> q
deque(['e', 'f', 'v', 'u', 'a', 'b', 'c', 'd'])
>>> q.rotate(-2)          # 将头部的两个元素移动到尾部
>>> q
deque(['v', 'u', 'a', 'b', 'c', 'd', 'e', 'f'])

其中,rotate方法用于旋转,如果旋转参数n大于0,表示将队列右端的n个元素移动到左端,否则相反

以上是关于python基础collections的使用的主要内容,如果未能解决你的问题,请参考以下文章

python collections模块-标准库

Python3基础 list append 向尾部添加一个元素

Python3基础 list append 向尾部添加一个元素

Python3基础 extend向列表尾部插入多个元素

Python基础 collections模块

python开发模块基础:collections模块