Python模块: collections

Python作为一个“内置电池”的编程语言,标准库里面拥有非常多好用的模块。比如今天想给大家 介绍的 collections就是一个非常好的例子。

基本介绍

我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型:

  • namedtuple(): 生成可以使用名字来访问元素内容的tuple子类
  • deque: 双端队列,可以快速的从另外一侧追加和推出对象
  • Counter: 计数器,主要用来计数
  • OrderedDict: 有序字典
  • defaultdict: 带有默认值的字典

1,namedtuple()

Python中存储系列数据,比较常见的数据类型有list,除此之外,还有tuple数据类型。相比与list,tuple中的元素不可修改,在映射中可以当键使用。tuple元组的item只能通过index访问,collections模块namedtuple子类不仅可以使用item的index访问item,还可以通过item的name进行访问。可以将namedtuple理解为c中的struct结构,其首先将各个item命名,然后对每个item赋予数据。

coordinate = namedtuple('Coordinate', ['x', 'y'])
co = coordinate(10,20)
print (co.x,co.y)
print (co[0],co[1])
co = coordinate._make([100,200])
print (co.x,co.y)
co = co._replace(x = 30)
print (co.x,co.y)


10 20
10 20
100 200
30 200
from collections import namedtuple

websites = [
    ('Sohu', 'http://www.google.com/', u'张朝阳'),
    ('Sina', 'http://www.sina.com.cn/', u'王志东'),
    ('163', 'http://www.163.com/', u'丁磊')
]

Website = namedtuple('Websites', ['name', 'url', 'founder'])
# Website  对象名
# 参数'Websites': Websites(name='Sohu', url='http://www.google.com/', founder='张朝阳')
#               指打印显示的名字

for website in websites:
    website = Website._make(website)


    print(website)
    '''
    Websites(name='Sohu', url='http://www.google.com/', founder='张朝阳')
    Websites(name='Sina', url='http://www.sina.com.cn/', founder='王志东')
    Websites(name='163', url='http://www.163.com/', founder='丁磊')
    '''

    print(website.name, website.url, website.founder)
    '''
    Sohu http://www.google.com/ 张朝阳
    Sina http://www.sina.com.cn/ 王志东
    163 http://www.163.com/ 丁磊
    '''

2,deque ()

参考:https://blog.csdn.net/u010339879/article/details/80767293

deque 是一个双端队列, 如果要经常从两端append 的数据, 选择这个数据结构就比较好了, 如果要实现随机访问,不建议用这个,请用列表.
deque 优势就是可以从两边append ,appendleft 数据. 这一点list 是没有的.

指定队列长度

from collections import deque
#  可以指定 队列的长度
mydeque = deque(maxlen=10)
print(mydeque.maxlen)  # 10

从两端添加元素

# 默认从右边加入
mydeque.append(10)
mydeque.append(12)
print(mydeque)  # deque([10, 12], maxlen=10)

# 也可以从左边加入
mydeque.appendleft('a')
mydeque.appendleft('b')
mydeque.appendleft('c')
print(mydeque)  # deque(['c', 'b', 'a', 10, 12], maxlen=10)

取队列元素

# 出队列,返回出队列的元素 
# 可以从左边也可以从右边 出队列 
mydeque.pop()
mydeque.popleft()

查看队列元素个数

# 查看 队列里面元素个数
print(len(mydeque))

统计元素的个数

# 统计元素的个数
#统计a 有几个
print(mydeque.count('a'))

在某个位置insert一个元素

# insert(i, x)
# Insert x into the deque at position i.
d1
Out[31]: deque([10, 12, 13, 14])
d1.insert(2,'frank')
d1
Out[33]: deque([10, 12, 'frank', 13, 14])

翻转操作

#翻转操作
# deque.reverse()

mydeque
Out[52]: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
mydeque.reverse()
mydeque
Out[54]: deque([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])

remove 移除某个元素

mydeque
Out[23]: deque(['e', 'd', 'c', 'b', 'a', 10, 12])
mydeque.remove(10)
mydeque
Out[25]: deque(['e', 'd', 'c', 'b', 'a', 12])

清空队列元素 clear

mydeque
Out[46]: deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
mydeque.clear
Out[47]: <function deque.clear>
mydeque.clear()
mydeque
Out[49]: deque([])

重要方法说明

  • rotate 方法
    移动到最后一个,占用第一个位置,循环移动, value 是步长
    rotate(value) 对队列实行旋转操作(每个元素依次向后移动value步,最后一个移动到第一个算一步)

    from collections import deque	
    
    d = deque()
    d.extend(['a', 'b', 'c', 'd', 'e'])
    d.rotate(2)  # 指定次数,默认1次
    print(d) # deque(['d', 'e', 'a', 'b', 'c'])
    
  • maxlen要说明一下, 如果指定了 maxlen
    如果构建deque 的时候,指定了maxlen, 则可以通过 d.maxlen 来获得dueue的最大长度.
    如果插入的数据大于 maxlen 则会自动删除旧的元素.删除 什么元素,取决于, 从哪边添加数据.来看一下例子.

    d = deque(list(range(5)),maxlen=5)
    d
    Out[21]: deque([0, 1, 2, 3, 4])
    
    d.maxlen
    Out[26]: 5
    
    
    # 从左边添加元素, # 元素4 被挤出 队列
    
    d.appendleft('frank')
    d
    Out[23]: deque(['frank', 0, 1, 2, 3])
    
    # 从右边添加元素, 元素 'frank'  被挤出队列.
    d
    Out[23]: deque(['frank', 0, 1, 2, 3])
    d.append('xiaoming')
    d
    Out[25]: deque([0, 1, 2, 3, 'xiaoming'])
    
    

3,Counter()

参考:http://www.pythoner.com/205.html
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)

创建
下面的代码说明了Counter类创建的四种方法:

>>> c = Counter()  # 创建一个空的Counter类
>>> c = Counter('gallahad')  # 从一个可iterable对象(list、tuple、dict、字符串等)创建
>>> c = Counter({'a': 4, 'b': 2})  # 从一个字典对象创建
>>> c = Counter(a=4, b=2)  # 从一组键值对创建

计数值的访问与缺失的键

当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。

>>> c = Counter("abcdefgab")
>>> c["a"]
2
>>> c["c"]
1
>>> c["h"]
0

计数器的更新(updatesubtract

可以使用一个iterable对象或者另一个Counter对象来更新键值。

计数器的更新包括增加和减少两种。其中,增加使用update()方法

>>> c = Counter('which')
>>> c.update('witch')  # 使用另一个iterable对象更新
>>> c['h']
3
>>> d = Counter('watch')
>>> c.update(d)  # 使用另一个Counter对象更新
>>> c['h']
4

减少则使用subtract()方法

>>> c = Counter('which')
>>> c.subtract('witch')  # 使用另一个iterable对象更新
>>> c['h']
1
>>> d = Counter('watch')
>>> c.subtract(d)  # 使用另一个Counter对象更新
>>> c['a']
-1

键的删除

当计数值为0时,并不意味着元素被删除,删除元素应当使用del

>>> c = Counter("abcdcba")
>>> c
Counter({'a': 2, 'c': 2, 'b': 2, 'd': 1})
>>> c["b"] = 0
>>> c
Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0})
>>> del c["a"]
>>> c
Counter({'c': 2, 'b': 2, 'd': 1})

elements()

返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。元素排列无确定顺序,个数小于1的元素不被包含。

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> list(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common([n])

most_common(n)按照counter的计数,按照降序,返回前n项组成的list; n忽略时返回全部
返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,排列是无确定顺序的。

>>> c = Counter('abracadabra')
>>> c.most_common()
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
>>> c.most_common(3)
[('a', 5), ('r', 2), ('b', 2)]

算术和集合操作
+-&|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。需要注意的是,得到的Counter对象将删除小于1的元素。

>>> c = Counter(a=3, b=1)
>>> d = Counter(a=1, b=2)
>>> c + d  # c[x] + d[x]
Counter({'a': 4, 'b': 3})
>>> c - d  # subtract(只保留正数计数的元素)
Counter({'a': 2})
>>> c & d  # 交集:  min(c[x], d[x])
Counter({'a': 1, 'b': 1})
>>> c | d  # 并集:  max(c[x], d[x])
Counter({'a': 3, 'b': 2})
常见做法:
sum(c.values())                 # 继承自字典的.values()方法返回values的列表,再求和
c.clear()                       # 继承自字典的.clear()方法,清空counter
list(c)                         # 返回key组成的list
set(c)                          # 返回key组成的set
dict(c)                         # 转化成字典
c.items()                       # 转化成(元素,计数值)组成的列表
Counter(dict(list_of_pairs))    # 从(元素,计数值)组成的列表转化成Counter
c.most_common()[:-n-1:-1]       # 最小n个计数的(元素,计数值)组成的列表
c += Counter()                  # 利用counter的相加来去除负值和0的值

4,OrderedDict()

Python中的字典对象可以以“键:值”的方式存取数据。OrderedDict是它的一个子类,实现了对字典对象中元素的排序。

import collections
 
print('Regular dictionary:')
d={}
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
    print( k,v)
 
print( '\nOrderedDict:')
d=collections.OrderedDict()
d['a']='A'
d['b']='B'
d['c']='C'
for k,v in d.items():
    print( k,v)
Regular dictionary:
a A
c C
b B

OrderedDict:
a A
b B
c C

可以看到,同样是保存了ABC三个元素,但是使用OrderedDict会根据放入元素的先后顺序进行排序。由于进行了排序,所以OrderedDict对象的字典对象,如果其顺序不同那么Python也会把他们当做是两个不同的对象,比如下面的代码:

import collections
 
print('Regular dictionary:')
d1={}
d1['a']='A'
d1['b']='B'
d1['c']='C'
 
d2={}
d2['c']='C'
d2['a']='A'
d2['b']='B'
 
print(d1==d2)
 
print('\nOrderedDict:')
d1=collections.OrderedDict()
d1['a']='A'
d1['b']='B'
d1['c']='C'
 
d2=collections.OrderedDict()
d2['c']='C'
d2['a']='A'
d2['b']='B'
 
print(d1==d2)
Regular dictionary:
True

OrderedDict:
False

fromkeys(指定一个列表,把列表中的值作为字典的key,生成一个字典)

import collections

dic = collections.OrderedDict()
name = ['tom','lucy','sam']
print(dic.fromkeys(name))
print(dic.fromkeys(name,20))

#输出:OrderedDict([('tom', None), ('lucy', None), ('sam', None)])
#     OrderedDict([('tom', 20), ('lucy', 20), ('sam', 20)])

items()(返回由“键值对组成元素“的列表)

import collections

dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
print(dic.items())

#输出:odict_items([('k1', 'v1'), ('k2', 'v2')])

keys()(获取字典所有的key,返回一个列表)

import collections

dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
print(dic.keys())

# 输出:odict_keys(['k1', 'k2'])

values()(获取字典所有的value,返回一个列表)

import collections

dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
dic['k3'] = 'v3'
print(dic.values())

# 输出:odict_values(['v1', 'v2', 'v3'])

5,defaultdict()

class collections.default([default_factory[, ...]])

返回一个类字典对象。defaultdict是内置类型dict的子类。他重写了父的一个方法并且增加了一个可以的实例变量。余下的功能与字典的一样,在这里就不写文档了。
第一个参数为default_factory属性提供初始值;default_factory的默认值为None.余下的参数被视为dict构造器的参数包括关键字参数

defaultdict 的例子
使用list作为default_factory,他很容易的将一个以键值形式表现的序列分组成一个字典列表

>>> 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])]

当每个key第一次被访问时,他们肯定没有在映射中:一个入口自动的被创建了使用default_factory函数返回一个空的列表。然后list.append()操作将值放入新的列表中。当key再次被访问时,查找工作正常(返回这个key的列表)然后list.append()操作为列表添加别外的值。这个技巧比等价的技艺(使用dict.setdefault())更简节,更快

>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> d.items()
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

default_factory设置成int使defaultdict对于计数非常有用

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> d.items()
[('i', 4), ('p', 2), ('s', 4), ('m', 1)]

当一个字每第一次被访问时,这个字母在映射中不存在,因此default_factory函数调用int()提供一个默认的0作为count。然后自增操作计算每个字母出现的次数,
int()函数总是返回0,因为他是常量函数的一个特殊的例子。一个更快更灵活的方式是创建一个常量函数

设置default_factoryset使defaultdict构建集合字典非常有用

>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> d.items()
[('blue', set([2, 4])), ('red', set([1, 3]))]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值