Python处理键映射值操作详解
作者:盆友圈的小可爱 发布时间:2021-03-21 03:14:53
作为一个学完Python基础知识的测试,暗喜终于可以像RD们自己写脚本处理任何场景吧,如何优雅地写出来代码,接下来开启进阶版的Python。
本期浅谈一下,collection模块关于键值常用的方法,跟着我一起涨知识吧~
1. 问题背景
在LeetCode刷题时候,经常会创建哈希表来辅助存储数据操作,一说哈希表,小白的我一马无脑就打出了一行tmp = {}
。如果在高级点的可以写成 tmp = dict()
。
直到有一天,遇到1个key存在多个value的问题。那要创建一个value是列表类型的字典,怎么创建呐?(基础太差,知道一对一的)。思考许久删了写写了删,终于使用for循环判断,搞定字典存储key-多个value的值,代码如下:
tmp = {}
students = ["C","A","B","C","D","A","A"]
for index,st in enumerate(students):
if st not in tmp:
tmp[st] = []
tmp[st].append(index)
###
{'C': [0, 3], 'A': [1, 5, 6], 'B': [2], 'D': [4]}
###
饭后找大佬show code,可想而知被大佬的神通广大的见识,直呼涨知识了!。
在 Python内置库中,其实是有一个collection模块提供defaultdict() 方法来专门处理上述遇到的问题,使用defaultdict()实现如上需求,for循环中只需要一行代码即可
from collections import defaultdict
tmp2 = defaultdict(list)
for index,st in enumerate(students):
tmp2[st].append(index)
##
defaultdict(<class 'list'>, {'C': [0, 3], 'A': [1, 5, 6], 'B': [2], 'D': [4]})
###
听大佬说collection模块可不止这个,还有很多好玩的。带着疑问,去认识collection模块学习。
2. collections 概述
2.1 什么是collections
Python 内置collection模块对普通数据类型(如dict,list,tuple和set)进行扩展和补充。
Collection 模块提供9种扩展的数据类型对象,其中对dict字典扩展的就有5个对象(OrderedDict、ChainMap、defaultdict、UserDict、Counter)。
2.2 Collections 内部结构
Collections模块是集中了collections.abc模块和扩展数据类型如UserDict的容器集合模块, Python中内置的dict存在一些限制,不适合一些场景,因此collections模块提供一些扩展方法。
Collections.abc是从adc抽象基类中导出ABCMeta,abstractmethod进行二次封装成一系列关于集合类的接口如关于映射的mapping和mutilmapping抽象基类,用于判断是映射关系抽象类。
实例化映射方法,一般不会直接继承collections.abc抽象基类的,而是是继承Python内置的dict类对象或者collections.UserDict进行拓展。抽象基类作为一个定义映射关系的基本接口。 同时也可以对isinstance来判断该接口是不是映射类型。
port _collections_abc
tmp = {}
print(isinstance(tmp,collections.abc.Mapping))
###
True
###
2.3 collections 使用方法
Collections 模块提供多种场景的集合类型,在特定场景下,使用它内部的方法可以提高我们代码的运行效率。 collections 模块文档介绍,已经实现对Python 内置数据类型 list,set,tuple和dict都实现的了拓展。
Collections 模块使用时,需要进行提前导入
from collections import xxxxx
3. defaultdict 方法
回到第一节问题,当tmp[st]值不存在时,Python内部会抛出异常KeyError。
我们遇到该问题时,总想的可以对tmp[st]赋值为一个默认值default,即tmp.get(st,default)来消除异常情况。
但是当tmp[st]更新某个值时,需要再次不必要的get查询,导致代码低效。
因此collections模块提供针对快速处理的找不键的情况,提供两种方法:
setdefault(),对字典key值赋默认值
针对第一节,if判断部分可以直接改写为:
# if st not in tmp:
# tmp[st] = []
# tmp[st].append(index)
#
tmp.setdefault(st,[]).append(index)
虽然提前赋值后,从查询键值次数2到3次,减少一次,但是仍然还要进行插入操作
defaultdict(),对字典进行查找取值
Defaultdict()实现了专门在读取健值就能获取到一个默认值的方法,是通过继承dict进行定义的一个子类,在子类中__missing__方法处理keyerror异常
在第一节中,通过使用defaultdict()来优化,Python内部是怎么运行呢?
比如 tmp2 = defaultdict(list) 当 key- value 不存在tmp2时,tmp2[key]会被进行操作:
调用list()来建立一个new list,作为default_factory实例属性
把new list 作为value,赋值给key键,放在tmp2中 最后返回这个new list的引用
需要注意是,当defaultdict每天指定default_factory时,重新不存在的键会触发keyerror
然而,专门处理keyerror异常的是__missing__()方法,dict类中没有被定义,当__getitem__找不键时候,Python会自动调用__missing__()方法。
4. Counter 方法
在有些时候,我们需要对列表中元素出现的次数进行统计,按照常规思路,仍然要使用for循环查询更新,代码运行效率大大降低。
在 collections模块中提供了Counter()方法,相等于计数器。
那么,Python内部是怎么运行的呢?
Counter 会给键准备一个整数计数器 每更新一个键的时候都会增加这个计数器
Counter 支持对4种形式的写法:
创建空计数器:
tmp = Counter()
支持迭代对象如字符串:
tmp = Counter("juejin")
支持映射对象如字典:
tmp = Counter({"a":3,"b":4})
支持key=value形式:
tmp = Counter(jue=1,jin=2)
Counter对象还支持求出most_common([n])求前n最大的key-value字典等方法
来源:https://juejin.cn/post/7164673886183751717


猜你喜欢
- function $package(name) { &nb
- 一、软件包a) freetds-stable.gzb) php-5.2.12.tar.gz二、安装步骤a) tar zxvf freetds
- 1.理解mask()和setmask()一般是在pyqt绘图时常见,而且在显示不规则图形时更是常见。参考书籍上说:setMask()函数的作
- 目录假想场景基本思路pywinauto方案win32gui方案更一般的方案利用Python进行Excel自动化操作的过程中,尤其是涉及VBA
- 我们知道分析MySQL语句查询性能的方法除了使用EXPLAIN 输出执行计划,还可以让MySQL记录下查询超过指定时间的语句,我们将超过指定
- 这篇文章主要介绍了pyinstaller还原python代码过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- function cal_pace(d,h,m,s){ var distance = d; var hours = h;
- 变量什么是变量?变量是在程序运行时,能存储计算结果或能表示值得抽象概念。简单地说,变量就是在程序运行时,记录数据用的变量定义格式:变量名称=
- MYSQL中批量替换某个字段的部分数据,具体介绍如下所示:1.修改字段里的所有含有指定字符串的文字UPDATE 表A SET 字段B = r
- 如下所示:#coding=utf-8#读取图片 返回图片某像素点的b,g,r值import cv2import numpy as npimg
- 如下所示:python3:img_path = ' 'im = cv2.imdecode(np.fromfile
- 问题背景目前的linux发行版上,有很多安装了两个版本的python。我的机器上默认的版本为python 2.x。且在使用easy_inst
- 本文只讨论Oracle中最常见的索引,即是B-tree索引。本文中涉及的数据库版本是Oracle8i。 一. 查看系统表中的用户索引 在Or
- 一、循环语句介绍 1.循环语句理解循环语句允许我们执行一个语句或语句组多次,可以让我们的代码重复的去执行。2.循环语句示意图二、循
- 引入:Python中有个logging模块可以完成相关信息的记录,在debug时用它往往事半功倍一、日志级别(从低到高):DEBUG :详细
- 导入 python 库import matplotlib.pyplot as pltimport skimage.io as ioimpor
- Python中的frame是什么栈帧(frame)栈帧表示程序运行时函数调用栈中的某一帧。想要获得某个函数相关的栈帧,则必须在调用这个函数且
- 一、记事本源码#python简易记事本from tkinter import *from tkinter import messagebox
- 我想大家在用Sql2005一般都是.NET2005自带的SQL Server 2005是SQL Server2005 Express版本的,
- 所有编程语言都离不开循环。因此,默认情况下,只要有重复操作,我们就会开始执行循环。但是当我们处理大量迭代(数百万/十亿行)时,使用循环是一种