Python算法黑科技collection模块

  collection就是基于python基本数据类型并为之添加了一些新的功能,也可以说是提供了几种高级数据类型,在。

  这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。

功能 注释
deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面
Counter 字典的子类,提供了可哈希对象的计数功能
OrderedDict 字典的子类,保存了他们被添加的顺序
defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值
namedtuple 创建命名元组子类的工厂函数

deque双端队列

  deque本质上就是实现了数据结构中队列的升级版,双端队列可以高效的实现插入和删除的双向列表,适用于队列和栈。

双端队列支持线程安全,在双端队列的任何一端执行添加和删除操作,它们的内存效率几乎相同(时间复杂度为O(1))。

from collections import deque

q= deque(['a','b','c'])
q.append('1')
q.appendleft('2')

print(q)
#deque(['2', 'a', 'b', 'c', '1'])

ChainMap

  这个功能的目的是为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理。它通常比创建一个新字典和多次调用 update() 要快很多,因为我们这么做的话要新建一个数据结构,这样的话对空间和时间上的浪费都是不小得。

1、可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询,若该多个字典当中有相同的key时,只会显示第一个字典相对应的value

2、当对ChainMap进行修改的时候总是只会对第一个字典进行修改

3、new_child()方法实质上是在列表的第一个元素前放入一个字典,默认是{},而parents是去掉了列表开头的元素

from collections import ChainMap
a = {"x":1, "z":3}
b = {"y":2, "z":4}
c = ChainMap(a,b)
print(c)
print("x: %d, y: %d, z: %d" % (c["x"], c["y"], c["z"]))
print("x: %d, y: %d, z: %d, z: %d " % (c["x"], c["y"], c["z"], c["z"]))
输出:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
x: 1, y: 2, z: 3, z: 3       

Counter计数器

  Counter是对字典类型的补充,用于追踪值出现的次数,它继承于字典,用于计数可哈希的对象,计数的数值可以是正整数、负整数和零。

from collections import Counter
c = Counter('asdadiuhiuchizuha')
print(c)

输出:Counter({'a': 3, 'i': 3, 'u': 3, 'h': 3, 'd': 2, 's': 1, 'c': 1, 'z': 1})

OrderedDict有序字典

  OrderedDict和一般的dict类似,但是还具有记忆字典中存储的key的插入顺序。但是现在OrderDict可能用处不大了,因为从Python 3.7开始,一般的dict也具有这个特性。

  该功能按照需求使用,若最重要的是排序操作,而空间效率、迭代效率以及更新字典的性能是次要的,则使用该功能,否则用dict即可

  OrderedDict可以处理频繁的需要重排的操作,适合于Track最近的操作;

  判断两个OrderedDict是否相等同时要求顺序也相同;

  OrderedDictpopitem(last=True)中可以通过last参数控制pop哪一端的元素;

  OrderedDictmove_to_end(key, last=True)可以高效的将元素移至末尾;


defaultdict默认字典

  关于defaultdict,我们可以先看一下dict中一个类似功能的函数setdefault(k, d=None):

d = {}
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]

for k, v in s:
    d.setdefault(k, []).append(v)

sorted(d.items())
[out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

  在上述代码中,setdefault(k, d=[])一句话相当于做了两件事情:一是获取key为k的的value,二是若该key不存在则设置其值为[]。即,d.get(k, [])以及如果key不存在就设置d[k] = []。现在再回到defaultdictdefaultdict([default_factory[, ...]]),构造方法中default_factory默认是Nonedefaultdictdict的一个subclass,它重写了一个__missing__方法以及拥有一个default_factory属性。

  • __missing__(key)

    • 该方法在当key不存在时才会且仅被__getitem__()调用,所以当使用dict.get()方法获取一个不存在的键值时,返回结果为None,而不是使用default_factory

    • default_factoryNone时,索引一个不存在的key会引发KeyError异常;

    • default_factory不为None时,索引一个不存在的key则使用default_factory进行初始化并返回值

      from collections import defaultdict
      
      [in]:d2 = defaultdict(int ,a=1, b=2)
      [in]:d2['c']
      [out]:0
      
      [in]:d2 = defaultdict(int ,a=1, b=2)
      [in]:d2.get('c')
      [out]:None
          
      [in]:d2
      [out]:defaultdict(int, {'a': 1, 'b': 2})
      
      [in]:d1 = defaultdict(a=1, b=2)
      [in]:d1['c']
      [out]:KeyError: 'c'
      
  • default_factory

    该属性在上述 __missing__()函数中使用,由构造函数中的default_factory初始化,默认为None

    因此,上述例子可以使用defaultdict来实现如下:

    s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
    d = defaultdict(list)
    for k, v in s:
        d[k].append(v)
    
    sorted(d.items())
    [out]:[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
    

namedtuple具名元组

  见名知意,就是具有名字的元组,因为我们知道,元组是不可变类型,而且只能靠索引获得值,这里用具名元组目的就是让元组有名字方便查找

from collections import  namedtuple
# namedtuple('名称', [属性list]):
point = namedtuple('p',['x','y'])
p = point(1,2)
print(p.x) #1
print(p.y) #2

  这个可以用在函数返回多值的时候,因为是元组,这样写见名知意,为代码可读性提供了便利!

posted @ 2020-09-15 16:35  Lance_王  阅读(337)  评论(1编辑  收藏  举报