基本介绍

Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型,如下。这些类在平时Python代码中用处非常大,熟练掌握这个模块,可以大大简化Python代码,提高Python代码逼格。

import collections

print collections.__all__

['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict', 'Hashable','Iterable', 'Iterator', 'Sized', 'Container','Callable', 'Set', 'MutableSet','Mapping', 'MutableMapping', 'MappingView', 'KeysView', 'ItemsView', 'ValuesView', 'Sequence', 'MutableSequence']

本文主要介绍collections库中常用的几个类:

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

Counter类

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

Counter类的创建

from collections import Counter

c1 = Counter() # 创建一个空的Counter类

c2 = Counter('zhongguo') # 从一个可iterable对象(list、tuple、dict、字符串等)创建

c3 = Counter({'a': 5, 'b': 1}) # 从一个字典对象创建

c4= Counter(a=3, b=8) # 从一组键值对创

most_common()方法

s = 'Nothing is difficult if you put your heart into it'

c = Counter(s)

print c.most_common(5)

[(' ', 9), ('i', 7), ('t', 6), ('o', 4), ('u', 4)]

键值的访问与计数器的更新

c = Counter("zhongguo")

print c['z'],c['o'],c['l']

output:1,2,0

#注意:不同于字典键值查找,当查找的键值不存在是计数器返回为0

#第一种更新方式--updatez增加

c.update('ren') # 使用另一个iterable对象更新

print c['n'] #2

d = Counter('niubi')

c.update(d) # 使用另一个Counter对象更新

print c['n'] #4

#第2种更新方式--subtract减少

c = Counter("zhongguo")

c.subtract('ren')

print c['n'] #0

d = Counter('niubi')

c.update(d)

print c['n'] #-1(是可以为负数的)

elements()方法以及删除键值

c = Counter(a=2, b=1, c=0, d=-1)

list(c.elements())

#['a', 'a', 'b'] #小于或等于0的不显示了

#删除键值

del c['a']

print c

#Counter({'b': 1, 'c': 0, 'd': -1})

一些基本操作

c1 = Counter(a=1, b=2)

c2 = Counter(a=2, b=3)

print c1+c2

print c1-c2 #不返回0或者负数计数

#Counter({'b': 5, 'a': 3})

#Counter()

sum(c.values()) # 所有计数的总数

c.clear() # 重置Counter对象,注意不是删除

list(c) # 将c中的键转为列表

set(c) # 将c中的键转为set

dict(c) # 将c中的键值对转为字典

c += Counter() # 移除0和负值

defaultdict 类

defaultdict 是 dict 的子类,因此 defaultdict 也可被当成 dict 来使用,dict 支持的功能,defaultdict 基本都支持。但它与 dict 最大的区别在于,如果程序试图根据不存在的 key 采访问 dict 中对应的 value,则会引发 KeyError 异常;而 defaultdict 则可以提供一个 default_factory 属性,该属性所指定的函数负责为不存在的 key 来生成 value。

from collections import defaultdict

my_dict = {}

# 使用int作为defaultdict的default_factory

# 将key不存在时,将会返回int()函数的返回值

my_defaultdict = defaultdict(int)

print my_defaultdict['a'] # 0

print my_dict['a'] # KeyError

#与Counter性质类似

#上面分别创建了空的 dict 对象和 defaultdict 对象,当程序试图访问 defaultdict 中不存在的 key 对应的 value 时,程序输出 defaultdict 的 default_factory 属性(int 函数)的返回值 0;如果程序试图访问 dict 中不存在的 key 对应的 value,就会引发 KeyError异常。

对比dict操作

###dict####

s = [('Python', 1), ('Swift', 2), ('Python', 3), ('Swift', 4), ('Python', 9)]

d = {}

for k, v in s:

# setdefault()方法用于获取指定key对应的value.

# 如果该key不存在,则先将该key对应的value设置为默认值:[]

d.setdefault(k, []).append(v)

print list(d.items())

#需要处理 key 不存在的情况,如果该key不存在,setdefault()方法就会先为该key设置一个默认的value。

###defaultdict###

s = [('Python', 1), ('Swift', 2), ('Python', 3), ('Swift', 4), ('Python', 9)]

# 创建defaultdict,设置由list()函数来生成默认值

d = defaultdict(list)

for k, v in s:

# 直接访问defaultdict中指定key对应的value即可。

# 如果该key不存在,defaultdict会自动为该key生成默认值

d[k].append(v)

print(list(d.items()))

相比于普通dict是不是方便很多。

deque类

deque是一个双向链表,针对list连续的数据结构插入和删除进行优化。它提供了两端都可以操作的序列,这表示在序列的前后你都可以执行添加或删除操作。

from collections import deque

d=deque()

类似于list方法

d.append(3)

d.append(8)

print d

#deque([3,8])

print len(d) #2,

d[0] #3

d[-1] #8

d.pop() #5,默认pop()抛出的是队列的最后一个元素

d.leftpop() #3

长度限制

d=deque(maxlen=10)

for i in range(20):

d.append(i)

#deque(10, 11, 12, 13, 14, 15, 16', 17, 18, 19, 20], maxlen=10)

#当限制长度的deque增加超过限制数时,左边会自动删除,这也符合队列的性质。

extend()方法

d=deque([1,2,3,4,5])

d.extend([6])

#deque([1,2,3,4,5,6])

d.extendleft([-2,-1,0])

#deque([-2,-1,0, 1, 2, 3, 4, 5, 6])

rotate()方法

b=deque("ABCDEFG")

print b

b.rotate(2)

print b

b.rotate(3)

print b

#deque(['A', 'B', 'C', 'D', 'E', 'F', 'G'])

#deque(['F', 'G', 'A', 'B', 'C', 'D', 'E'])

#deque(['C', 'D', 'E', 'F', 'G', 'A', 'B'])

OrderedDict类

OrderedDict 也是 dict 的子类,其最大特征是,它可以“维护”添加 key-value 对的顺序。简单来说,就是先添加的 key-value 对排在前面,后添加的 key-value 对排在后面。相比于dict更加灵活。

基础性质

from collections import OrderedDict

# 创建OrderedDict对象

dx = OrderedDict(b=5, c=2, a=7)

print dx # OrderedDict([('b', 5), ('c', 2), ('a', 7)])

d = OrderedDict()

# 向OrderedDict中添加key-value对

d['Python'] = 89

d['Swift'] = 92

d['Kotlin'] = 97

d['Go'] = 87

# 遍历OrderedDict的key-value对

for k,v in d.items():

print k, v

顺序

# 创建普通的dict对象

my_data = {'Python': 20, 'Swift':32, 'Kotlin': 43, 'Go': 25}

# 创建基于key排序的OrderedDict

d1 = OrderedDict(sorted(my_data.items(), key=lambda t: t[0]))

# 创建基于value排序的OrderedDict

d2 = OrderedDict(sorted(my_data.items(), key=lambda t: t[1]))

print(d1) # OrderedDict([('Go', 25), ('Kotlin', 43), ('Python', 20), ('Swift', 32)])

print(d2) # OrderedDict([('Python', 20), ('Go', 25), ('Swift', 32), ('Kotlin', 43)])

print(d1 == d2) # False

# OrderedDict能维护key-value对的添加顺序,因此即使两个 OrderedDict中的key-value对完全相同,但只要顺序不同,程序在判断它们是否相等时也依然会返回false

特殊方法

  1. popitem(last=True):默认弹出并返回最右边(最后加入)的 key-value 对;如果将 last 参数设为 False,则弹出并返回最左边(最先加入)的 key-value 对。
  2. move_to_end(key, last=True):默认将指定的 key-value 对移动到最右边(最后加入);如果将 last 改为 False,则将指定的 key-value 对移动到最左边(最先加入)

d = OrderedDict.fromkeys('abcde')

# 将b对应的key-value对移动到最右边(最后加入)

d.move_to_end('b')

print(d.keys()) # odict_keys(['a', 'c', 'd', 'e', 'b'])

# 将b对应的key-value对移动到最左边(最先加入)

d.move_to_end('b', last=False)

print(d.keys()) # odict_keys(['b', 'a', 'c', 'd', 'e'])

# 弹出并返回最右边(最后加入)的key-value对

print(d.popitem()[0]) # e

# 弹出并返回最左边(最先加入)的key-value对

print(d.popitem(last=False)[0]) # b

namedtuple类

namedtuple() 是一个工厂函数,使用该函数可以创建一个 tuple 类的子类,该子类可以为 tuple 的每个元素都指定宇段名,这样程序就可以根据字段名来访问 namedtuple 的各元素了,也可以根据索引来访问 namedtuple 的各元素。

基本属性

namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)

  • typename:该参数指定所创建的 tuple 子类的类名,相当于用户定义了一个新类。
  • field_names:该参数是一个字符串序列,如 ['x','y']。此外,field_names 也可直接使用单个字符串代表所有字段名,多个字段名用空格、逗号隔开,如 'x y' 或 'x,y'。任何有效的 Python 标识符都可作为字段名(不能以下画线开头)。有效的标识符可由字母、数字、下画线组成,但不能以数字、下面线开头,也不能是关键字(如 return、global、pass、raise 等)。
  • rename:如果将该参数设为 True,那么无效的字段名将会被自动替换为位置名。例如指定 ['abc','def','ghi','abc'],它将会被替换为 ['abc', '_1','ghi','_3'],这是因为 def 字段名是关键字,而 abc 字段名重复了。
  • verbose:如果该参数被设为 True,那么当该子类被创建后,该类定义就被立即打印出来。
  • module:如果设置了该参数,那么该类将位于该模块下,因此该自定义类的 __module__ 属性将被设为该参数值。

from collections import namedtuple

# 定义命名元组类:Point

Point = namedtuple('Point', ['x', 'y'])

# 初始化Point对象,即可用位置参数,也可用命名参数

p = Point(11, y=22)

# 像普通元组一样用根据索引访问元素

print(p[0] + p[1]) # 33

# 执行元组解包,按元素的位置解包

a, b = p

print(a, b) # 11, 22

# 根据字段名访问各元素

print(p.x + p.y) # 33

print(p) # Point(x=11, y=22)

方法

  • _make(iterable):类方法。该方法用于根据序列或可迭代对象创建命名元组对象。
  • _asdict():将当前命名元组对象转换为 OrderedDict 字典。
  • _replace(**kwargs):替换命名元组中一个或多个字段的值。
  • _source:该属性返回定义该命名元组的源代码。
  • _fields:该属性返回该命名元组中所有字段名组成的元组。

my_data = ['East', 'North']

# 创建命名元组对象

p2 = Point._make(my_data)

print(p2) # Point(x='East', y='North')

# 将命名元组对象转换成OrderedDict

print(p2._asdict()) # OrderedDict([('x', 'East'), ('y', 'North')])

# 替换命名元组对象的字段值

p2._replace(y='South')

print(p2) # Point(x='East', y='North')

# 输出p2包含的所有字段

print(p2._fields) # ('x', 'y')

# 再次定义一个命名元组类

Color = namedtuple('Color', 'red green blue')

# 再次定义命名元组类,其字段由Point的字段加上Color的字段

Pixel = namedtuple('Pixel', Point._fields + Color._fields)

# 创建Pixel对象,分别为x、y、red、green、blue字段赋值

pix = Pixel(11, 22, 128, 255, 0)

print(pix) # Pixel(x=11, y=22, red=128, green=255, blue=0)

总结

看过上面的介绍是不是对collections模块有一定的理解了,是不是也已经知道了它的重要性,总之一句话,理解这个模块的各种方法实现,能够让你的代码有事半功倍的效果,而且相比传统的list,dict,用它可以让你的代码逼格更高,数不多说,快去学习了。

python dict根据value找对应的key_一个不得不了解的Python库——collections相关推荐

  1. thonny python ide_学习用 Thonny 写代码:一个面向初学者的Python IDE

    原标题:学习用 Thonny 写代码:一个面向初学者的Python IDE 编译自: https://fedoramagazine.org/learn-code-thonny-python-ide-b ...

  2. python逻辑运算的一些流程图_Python大牛历时一个月打造的Python系统学习流程图,超详细!...

    对于刚开始接触Python的小伙伴来说,没有思路方法,不知道从何开始学习,把软件环境安装好后就不知所措了!接下来我给大家分享下多位大牛倾力打造的python系统学习流程,一个月才设计完的! Pytho ...

  3. python通过内置的什么函数打开一个文件_利用python进行文件操作

    这篇文章主要介绍了如何利用python进行文件操作,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下 什么是文件 文件是系统存储区域的一个命名位置,用来存储一些信息,便于后续访问.能够在非 ...

  4. python实现按键精灵找色点击功能,使用pywin32和Pillow库

    Python图片处理模块PIL(pillow) pywin32的主要作用 1.捕获窗口:2.模拟鼠标键盘动作:3.自动获取某路径下文件列表:4.PIL截屏功能 找色点击功能思路: 抓取当前屏幕快照,指 ...

  5. python deque函数_一个不得不了解的Python库——collections

    基本介绍 Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型,如下.这些 ...

  6. 一个用python做的完整项目_我从一个小项目学习Python编程的全过程(二)

    在(一)中的时候我们分析了如何获取所有人无忧币的统计情况,接下来开始学着写代码了: 首先第一步我们得把第一个页面的源代码:#coding:utf-8 import urllib url = 'http ...

  7. python计算机视觉编程(全)(强烈推荐)_推荐一个计算机视觉图书:python计算机视觉编程...

    编辑部的主页:好像没啥用 每章的代码,github上面的:中文版 github上面,英文版: 项目主页: 中文在线的书: 然后下载安装 安装好了以后,点击自动的编辑器: 新建工程,插入代码:# -*- ...

  8. python 返回函数 变量_你如何设置一个变量等于由python函数返回的值

    我试图设计一个系统,允许我在点击时将精灵移动到光标位置,类似于RuneScape,玩家将移动到鼠标在屏幕上单击的位置.以下是我的代码如下: for event in pygame.event.get ...

  9. python打开exe文件并传递信息_打开一个.exe文件并用Python为其提供输入参数

    试试这个:from subprocess import Popen, check_output, check_call, PIPE, call get_input = input("What ...

最新文章

  1. python3调用OCR识别
  2. QT5 动态链接库的创建和使用
  3. aws lambda使用_使用Lambda,Api Gateway和CloudFormation在AWS云上使用Java
  4. TensorFlow8-mnist手写数字识别入门
  5. 后端返回页面ajax的处理
  6. java中来获取UUID
  7. 企业管理器控制台本地无法访问
  8. php sizeof函数,sizeof()的简单介绍
  9. 彻底搞懂Html5本地存储技术(一)
  10. 天线多频设计方法精讲
  11. 计算机职业规划500字中专,计算机中专生职业规划范文500字中专生职业生涯规划书范文.doc...
  12. 【STM32】 SG90舵机
  13. Mark 韦氏拼音 邮政式拼音 和汉语拼音
  14. 到底什么是爬虫技术?简谈爬虫概念
  15. 电商短视频运营应该怎么做
  16. Android 文件中断续传
  17. 产品介绍 | 51LA短链分发平台
  18. JS判断客户端是Android还是iOS
  19. SpringAOP原理+使用
  20. 截图任意识别翻译--天若OCR文字识别大神纯净版

热门文章

  1. 026_html表单
  2. Java中继承、接口、多态的作用详解(纯理论)
  3. 从零开始搭建Android框架系列
  4. Oralce 使用SQL中的exists 和not exists 用法详解
  5. 苹果开发着账号:个人、公司、企业账号的申请流程
  6. CAD2019软件安装教程
  7. java 张龙_张龙 JAVA5新特性学习笔记
  8. fastdfs 测试客户端_Nginx+FastDFS+MacOS图片服务器的搭建
  9. AspectJ对AOP的实现
  10. 应用基础计算机一级的题目,计算机应用基础一级模拟题