集合模块

  相对于 Python 中内置的称为链表、集合、字典和元组的默认容器类型来说,集合模块( collection module )提供了高性能的备选方案( alternative )。

  简单地看看集合模块中如下的容器类型:

    1 ) deque :一个链表容器的备选方案,支持在队列两端快速插入和弹出( pop )。

    2 ) defaultdict : dict 的子类,它为类型提供了工厂函数,用于提供缺省值。

    3 ) orderedDict : dict 的子类,它记录了关键字插入的顺序。

    4 ) Counter : dict 子类,用于保存可哈希类型的计数和统计信息。

    5 ) ChainMap :带有一个类似字典接口的类,用于持续跟踪多重映射。

    6 ) namedtuple :用于创建类似元组的类的类型,带有命名字段。

  1 . deque

  一个双端队列( double ended queue )像一个链表,但和链表不同,它支持近乎常量时间( O ( 1) )的从队列两端进行的增加和弹出操作,而链表对于在左端进行的弹出和插入操作,有一个 0 ( n )数量级的时间成本。

  双端队列也支持一些操作,比如旋动( rotation ) ,用于将列表中 k 个元素从表尾移动到表头,或者反过来,它们的平均性能为 O ( k )。这通常比链表中类似的操作稍微快一点,链表涉及切割( slicing )和追加( appending )操作:

  

# 定义一个双端队列
import collections dq = collections.deque() # append往右边添加一个元素
dq.append(1)
dq.append(2)
print(dq) # deque([1, 2]) # appendleft往左边添加一个元素
dq.appendleft(3)
dq.appendleft(4)
print(dq) # deque([4, 3, 1, 2]) # clear 清空队列
dq.clear()
print(dq) # deque([]) # copy浅拷贝
dq.append(1)
dq2 = dq.copy()
print(id(dq)) #
print(id(dq2)) # # count 返回指定元素的出现次数
dq3 = collections.deque()
dq3.append(1)
dq3.append(1)
print(dq3.count(1)) # # extend 从队列右端添加多个元素
dq4 = collections.deque()
dq4.append(1)
dq4.extend([2, 3, 4])
print(dq4) # deque([1, 2, 3, 4]) # extendleft 从队列左端添加多个元素 注意添加顺序
dq4.extendleft([5, 6, 7, 8])
print(dq4) # deque([8, 7, 6, 5, 1, 2, 3, 4]) # index 查找某个元素的索引位置,如果查无结果 会报异常 ValueError: xxx is not in deque
print(dq4.index(5)) #
print(dq4.index(2, 3, 7)) # 后面的两个参数可用于指定查找区间 # insert 在队列指定位置插入元素
dq4.insert(2, "c")
print(dq4) # deque([8, 7, 'c', 6, 5, 1, 2, 3, 4]) # pop 返回队列最右边的元素,并将其在队列中删除
print(dq4) # deque([8, 7, 'c', 6, 5, 1, 2, 3, 4])
x = dq4.pop()
print(x) #
print(dq4) # deque([8, 7, 'c', 6, 5, 1, 2, 3]) # popleft 返回最左边的元素,并将其在队列中删除
print(dq4) # deque([8, 7, 'c', 6, 5, 1, 2, 3])
y = dq4.popleft()
print(y) #
print(dq4) # deque([7, 'c', 6, 5, 1, 2, 3]) # remove 删除指定元素, 只删除一个值,从左向右查找
dq5 = collections.deque([1, 2, 3, 4, 5, 2])
print(dq5) # deque([1, 2, 3, 4, 5, 2])
dq5.remove(2)
print(dq5) # deque([1, 3, 4, 5, 2])
dq5.remove(2)
print(dq5) # deque([1, 3, 4, 5]) # reverse 反转队列
print(dq5) # deque([1, 3, 4, 5])
dq5.reverse()
print(dq5) # deque([5, 4, 3, 1]) # rotate 将右边元素放置到队列左边
dq5.rotate(2) # 可指定次数
print(dq5) # deque([3, 1, 5, 4])

  2 . defaultdict

  默认dict是dict子类, 它使用类型工厂提供对于字典关键字的默认值。

  在Python中,当在一个列表数据项上循环,并试着增加一个字典计数值的时候,我们会遇到一个常见问题,即有可能没有对应数据项的任何已存在的条目

  比如,对一个单词在一段文本中的出现次数进行计数:

counts = {}

for word in text.split():
word = word.lower().strip()
try:
counts[word] += 1
except KeyError:
counts[word] = 1

  再比如,试着对所有的字符串分组,相同长度的字符串放到一个字典中:

cities = ['Jakarta', 'Delhi', 'Newyork', 'Bonn', 'Kolkata', 'Bangalore', 'Seoul']

cities_len = {}
for city in cities:
clen = len(city)
# First create entry
if clen not in cities_len:
cities_len[clen] = []
cities_len[clen].append(city)

  一个defaultdict容器优雅地解决了这个问题,它通过定义一个类型工厂为任务没在字典中出现的关键字提供默认参数值。 默认工厂类型支持任意的默认类型, 而且默认值设为None。

  对于每种类型,它的空值是默认值,即:

  int -> 0

  [] -> list

  '' ->strings

  {} ->dict

  单词计数代码可以按照如下方式重写:

counts = collections.defaultdict(int)

for word in text.split():
word = word.split()
# Value is set to 0 and incremented by 1 in one go
counts[word] += 1

  类似地,根据字符串长度分组它们的代码如下:  

cities = ['Jakarta', 'Delhi', 'Newyork', 'Bonn', 'Kolkata', 'Bangalore', 'Seoul']

cities_len = collections.defaultdict(list)

for city in cities:
# Empty list is created as value and appended to in one go
cities_len[len(city)].append(city)

  3 . OrderedDict

  OrderedDict 是一个dict子类, 它记录了条目插入的顺序,它有点像一个字典和链表的结合体,它表现得像一个映射类型,但是在记录插入顺序,甚至支持诸如用于删除头尾条目的popitem方法上,也有类似链表的行为

cities = ['Jakarta', 'Delhi', 'Newyork', 'Bonn', 'Kolkata', 'Bangalore', 'Seoul']
cities_dict= collections.OrderedDict.fromkeys(cities)
print(cities_dict) # OrderedDict([('Jakarta', None), ('Delhi', None), ('Newyork', None), ('Bonn', None), ('Kolkata', None), ('Bangalore', None), ('Seoul', None)])
print(cities_dict.popitem()) # ('Seoul', None)
print(cities_dict.popitem(last=False)) #('Jakarta', None)

  比较和对照字典是如何改变顺序的,而OrderedDict容器是如何保持原有顺序的。

  这里给出了一些使用OrderedDict容器的做法。

  1)不丢失顺序地从一个容器中删除重复元素。

cities = ['Jakarta', 'Delhi', 'Newyork', 'Bonn', 'Kolkata', 'Bangalore', 'Bonn', 'Seoul', 'Delhi', 'Jakarta', 'Mumbai']

cities_odict = collections.OrderedDict.fromkeys(cities)
print(cities_odict.keys())

  2) 实现一个最近最少使用(LRU)的缓存字典。

  一个LRU缓存优先考虑最近被使用(或被访问)的条目,删除那些最少被使用的条目。这是一个常见的缓存算法,用在诸如Squid的HTTP缓存服务器中,也用在其他一些情况中,即需要维护一个被限制了大小的容器,这个容器优先保存最近被访问的条目。

  这里使用了OrderedDict的操作,即当删除了一个存在的关键字,然后再重新添加时,它被添加到了末尾(右端):

  

class LRU(collections.OrderedDict):
""" Least recently used cache dictionary""" def __init__(self, size=10):
self.size = size def set(self, key):
# if key is there delete and reinsert so
# it moves to end
if key in self:
del self[key] self[key] = 1
if len(self) > self.size:
# pop from left
self.popitem(lastp=False)
lru = LRU(5)
lru.set("bangalore")
lru.set("chennai")
lru.set("mumbai")
lru.set("bangalore")
lru.set("kolkata")
lru.set("delhi")
lru.set("chennai")
lru.set("kochi")
print(lru) # LRU([('bangalore', 1), ('kolkata', 1), ('delhi', 1), ('chennai', 1), ('kochi', 1)])

  因为关键字mumbai第一个被设置,之后没有再被设置过,所以它变成了最左边的一个,然后被删除了。

  注意:要删除的下一个关键字是 bangalore, 接着是 chennai,这是因为chennai在bangalore设置之后被多设置了一次

  4. Counter

  5. ChainMap

  6. Namedtuple

  

Python中的高性能容器--collections的更多相关文章

  1. Python面试题之容器(Collections)

    容器(Collections) Python附带一个模块,它包含许多容器数据类型,名字叫作collections.我们将讨论它的作用和用法.   我们将讨论的是:   defaultdict coun ...

  2. Python 中的容器 collections

    写在之前 我们都知道 Python 中内置了许多标准的数据结构,比如列表,元组,字典等.与此同时标准库还提供了一些额外的数据结构,我们可以基于它们创建所需的新数据结构. Python 附带了一个「容器 ...

  3. Python中collections模块

    目录 Python中collections模块 Counter defaultdict OrderedDict namedtuple deque ChainMap Python中collections ...

  4. Python中collections模块的使用

    本文将详细讲解collections模块中的所有类,和每个类中的方法,从源码和性能的角度剖析. 一个模块主要用来干嘛,有哪些类可以使用,看__init__.py就知道 '''This module i ...

  5. 转载:Python中collections模块

    转载自:Python中collections模块 目录 Python中collections模块 Counter defaultdict OrderedDict namedtuple deque Ch ...

  6. python中的list, dict, tuple以及collections模块的基本用法

    1.关于list的一些基本用法 # 创建没有初值的列表 list1=[] # 创建有初值的列表 list2=['this','is','a','list'] # 创建给定长度但初值不确定的列表 lis ...

  7. python中的collections

    python中有大量的内置模块,很多是属于特定开发的功能性模块,但collections是属于对基础数据的类型的补充模块,因此,在日常代码中使用频率更高一些,值得做个笔记,本文只做主要关键字介绍,详细 ...

  8. Python中的collections模块

    Python中内置了4种数据类型,包括:list,tuple,set,dict,这些数据类型都有其各自的特点,但是这些特点(比如dict无序)在一定程度上对数据类型的使用产生了约束,在某些使用场景下效 ...

  9. python中的0,None,False,空容器

    在Python中,None.空列表[].空字典{}.空元组().0等一系列代表空和无的对象会被转换成False.除此之外的其它对象都会被转化成True. 1.0等于False,这点要注意. 2.空的l ...

随机推荐

  1. C++中vector的使用总结

    vector简单说明 vector也是一个容器,并且是个顺序容器.顺序容器有可变长数组vector.双向链表list.双端队列deque. 顺序容器的定义,是因为容器元素的位置和他们的值大小无关,也就 ...

  2. java stackoverflowerror与outofmemoryerror区别

    1.stackoverflow: 每当java程序启动一个新的线程时,java虚拟机会为他分配一个栈,java栈以帧为单位保持线程运行状态:当线程调用一个方法是,jvm压入一个新的栈帧到这个线程的栈中 ...

  3. linux命令之------部分细节点

    创建文件夹/文件命令以及清除模式 mkdir +文件夹名字 touch +文件名字 rm -fr 删除文件,文件夹 -f强制删除 -r是递归 查询linux下所有启动的线程: ps -ef|grep ...

  4. SpringCloud:搭建基于Gateway的微服务网关(一)

    1.需求 最近在尝试着写一个开放平台,于是先搭建网关. 作用:统一的请求入口,完成对请求的跟踪,限流(未做),鉴权,分发,封装响应 2.工作原理 2.1.请求 在开放平台中申请对接口的使用,申请通过后 ...

  5. 如果用了flex去加一个箭头怎么让他剧中

    左边是做了一个flex:1 右边是span的display:inline-block样式 父元素 .search-car-arrow display flex align-items center' ...

  6. 《微信小程序商城开发实战》唐磊,全网真实评价截图,不吹不黑,全部来自网友的真实评价

    偶尔看了下网友的销量和评价,感觉还不错,因为市面上大多关于小程序的书籍可能写的不够全面,要么只是点到为止的大致罗列,要么就是只简单介绍一下小程序的 界面设计这块.这样很难给学习小程序开发的人一个完成的 ...

  7. MyBatis(九):Mybatis Java API批量操作(增、删、改、查)

    最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...

  8. DateUtils.formate()函数的“bug”

    写在前面 项目功能测试, 日期格式转换出现个诡异的问题, 转换后的时间总是和系统当前时间相差8小时, 问题是另一个项目和这个代码完全一样, DateUtils.java, 包括formatDate() ...

  9. linux里安装使用svn

    1.安装 sudo apt-get install subversion 2.checkout工程 svn checkout svn://192.168.0.3/测试工具 /home/testtool ...

  10. mysql 得到指定时间段的日期

    set @startDate='2019-01-01'; set @endDate='2019-04-01'; DAY) AS DAY FROM ( SELECT a.a ) AS a ) AS b ...