Fluent Python 笔记 第 3 章 字典和集合

news2024/11/28 14:53:02

3.1 泛映射类型

只有可散列 的数据类型才能用作这些映射里的键

字典构造方法:

>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True

还有字典推导

3.2 字典推导

DIAL_CODES = [
    (86, 'China'),
    (91, 'India'),
    ]
country_code = {country: code for code, country in DIAL_CODES}

3.3 常见的映射方法

用setdefault处理找不到的键

index.setdefault(word, []).append(location)

3.4 映射的弹性键查询

3.4.1 defaultdict:处理找不到的键的一个选择

在实例化一个 defaultdict 的时候,需要给构造方法提供一个可调用对象,这 个可调用对象会在 __getitem__ 碰到找不到的键的时候被调用,让 __getitem__ 返回某种 默认值。

defaultdict 里的 default_factory 只会在 __getitem__ 里被调用,在其他的 方法里完全不会发挥作用。比如,dd 是个 defaultdict,k 是个找不到的键, dd[k] 这个表达式会调用 default_factory 创造某个默认值,而 dd.get(k) 则 会返回 None。

index = collections.defaultdict(list)

3.4.2 特殊方法__missing__

__missing__ 方法只会被 __getitem__ 调用(比如在表达式 d[k] 中)。提供 __missing__ 方法对 get 或者 __contains__(in 运算符会用到这个方法)这些方法的使用没有影响。这也是在上一节最后的警告中提到,defaultdict 中 的 default_factory 只对 __getitem__ 有作用的原因。

class StrKeyDict0(dict):
    def __missing__(self, key):
        if isinstance(key, str):
            raise KeyError(key) return self[str(key)]
    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default
    def __contains__(self, key):
        return key in self.keys() or str(key) in self.keys()

下面来看看为什么 isinstance(key, str) 测试在上面的 __missing__ 中是必需的。
如果没有这个测试,只要 str(k) 返回的是一个存在的键,那么 __missing__ 方法是没问题 的,不管是字符串键还是非字符串键,它都能正常运行。但是如果 str(k) 不是一个存在的 键,代码就会陷入无限递归。这是因为 __missing__ 的最后一行中的 self[str(key)] 会调 用 __getitem__,而这个 str(key) 又不存在,于是 __missing__ 又会被调用。为了保持一致性,__contains__ 方法在这里也是必需的。这是因为 k in d 这个操作会调用 它,但是我们从 dict 继承到的 __contains__ 方法不会在找不到键的时候调用 __missing__ 方法。__contains__ 里还有个细节,就是我们这里没有用更具 Python 风格的方式——k in my_dict——来检查键是否存在,因为那也会导致 __contains__ 被递归调用。为了避免这 一情况,这里采取了更显式的方法,直接在这个 self.keys() 里查询

3.5 字典的变种

collections.OrderedDict

这个类型在添加键的时候会保持顺序,因此键的迭代次序总是一致的。OrderedDict 的 popitem 方法默认删除并返回的是字典里的最后一个元素,但是如果像 my_odict. popitem(last=False) 这样调用它,那么它删除并返回第一个被添加进去的元素。

collections.ChainMap

该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当 作一个整体被逐个查找,直到键被找到为止。这个功能在给有嵌套作用域的语言做解 释器的时候很有用,可以用一个映射对象来代表一个作用域的上下文。在 collections 文 档 介 绍 ChainMap 对 象 的 那 一 部 分(https://docs.python.org/3/library/collections.html# collections.ChainMap)里有一些具体的使用示例,其中包含了下面这个 Python 变量查 询规则的代码片段:

import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))

collections.Counter

这个映射类型会给键准备一个整数计数器。每次更新一个键的时候都会增加这个计数 器。所以这个类型可以用来给可散列表对象计数,或者是当成多重集来用——多重集合 就是集合里的元素可以出现不止一次。Counter 实现了 + 和 - 运算符用来合并记录,还 有像 most_common([n]) 这类很有用的方法。most_common([n]) 会按照次序返回映射里最 常见的 n 个键和它们的计数

>>> ct = collections.Counter('abracadabra')
>>> ct
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
>>> ct.update('aaaaazzz')
>>> ct
Counter({'a': 10, 'z': 3, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
>>> ct.most_common(2)
[('a', 10), ('z', 3)]

colllections.UserDict

这个类其实就是把标准 dict 用纯 Python 又实现了一遍。

3.6 子类化UserDict

import collections

class StrKeyDict(collections.UserDict): ➊
    def __missing__(self, key): ➋ 
        if isinstance(key, str):
            raise KeyError(key)
        return self[str(key)]
    def __contains__(self, key):
        return str(key) in self.data ➌
    def __setitem__(self, key, item): 
        self.data[str(key)] = item
  • __contains__ 则更简洁些。这里可以放心假设所有已经存储的键都是字符串。因此,只
    要在 self.data 上查询就好了,并不需要像 StrKeyDict0 那样去麻烦 self.keys()。
  • __setitem__ 会把所有的键都转换成字符串。由于把具体的实现委托给了 self.data 属
    性,这个方法写起来也不难。

3.7 不可变映射类型

from types import MappingProxyType

d = {1:'A'}
d_proxy = MappingProxyType(d)

可以通过 d 改,d_proxy 可以看到改动,但不能修改。

3.8 集合论

集合中的元素必须是可散列的,set 类型本身是不可散列的,但是 frozenset 可以。因此 可以创建一个包含不同 frozenset 的 set。

3.8.1 集合字面量

如果要创建一个空集,你必须用不带任何参数的构造方法 set()。

frozenset(range(10))
frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})

3.8.2 集合推导

{fc(i) for i in *** if ***)}

3.8.3 集合的操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.9 dict和set的背后

3.9.1 一个关于效率的实验

快就完事

3.9.2 字典中的散列表

1. 散列值和相等性

如果两个对象在比较的时候是相等的,那它们的散列值必须相等,否则散列表就不能正常运行了。

2. 散列表算法

Python 首 先 会 调 用 hash(search_key) 来 计 算 search_key 的散列值,把这个值最低的几位数字当作偏移量,在散列表里查找表元(具 体取几位,得看当前散列表的大小)。若找到的表元是空的,则抛出 KeyError 异常。若不 是空的,则表元里会有一对found_key:found_value。这时候Python会检验search_key == found_key 是否为真,如果它们相等的话,就会返回 found_value。

3.9.3 dict的实现及其导致的结果

  1. 键必须是可散列的
  2. 字典在内存上的开销巨大。如果你需要存放数量巨大的记录,那么放在由元组或是具名元组构成的列表中会是比较好的选择。
  3. 键查询很快
  4. 键的次序取决于添加顺序
  5. 往字典里添加新键可能会改变已有键的顺序

不要对字典同时进行迭代和修改。如果想扫描并修改一个字典,最好分成两步 来进行:首先对字典迭代,以得出需要添加的内容,把这些内容放在一个新字典里;迭代 结束之后再对原有字典进行更新。

3.9.4 set的实现以及导致的结果

和前一部分一样

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/335656.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5. Spring 事务

文章目录1. Spring 事务简介2. Spring 事务角色3. Spring 事务属性3.1 事务配置3.2 案例:转账业务追加日志3.3 事务传播行为1. Spring 事务简介 Spring 事务作用:在数据层或业务层保障一系列的数据库操作同成功、同失败。 数据层有事务我们可以理解&am…

多传感器融合定位十三-基于图优化的建图方法其二

多传感器融合定位十二-基于图优化的建图方法其二3.4 预积分方差计算3.4.1 核心思路3.4.2 连续时间下的微分方程3.4.3 离散时间下的传递方程3.5 预积分更新4. 典型方案介绍4.1 LIO-SAM介绍5. 融合编码器的优化方案5.1 整体思路介绍5.2 预积分模型设计Reference: 深蓝学院-多传感…

Vue3 - 自定义指令封装

Vue3 - 自定义指令封装一. 自定义指令封装1.1 全局/局部注册自定义聚焦指令1.2 自定义指令相关参数1.3 自定义指令参数传递二. 总结一. 自定义指令封装 vue中有很多内置的指令,我们一般在开发中也经常用到,比如v-if,v-for等等。那么本篇文章…

Vue极简使用

Vue安装Vue模板语法安装Vue 安装nodejs 这里我安装的是14.5.4版本 https://nodejs.org/download/release/v14.15.4/解压后配置一下环境变量就行 安装cnpm镜像 (这个安装的版本可能过高,后面安装Vue可能出问题) npm install -g cnpm --registryhttps://registry…

二十二、Gtk4-ListView

GTK 4添加了新的列表对象GtkListView、GtkGridView和GtkColumnView。这个新特性在Gtk API参考—列表小构件概述中有描述。 GTK 4还有其他实现列表的方法。它们是GtkListBox和GtkTreeView,它们是从GTK 3接管的。在Gtk开发博客中有一篇关于Matthias Clasen所写的列表…

vscode执行Python输出exited with code=9009 in 0.655 seconds

vscode执行Python输出exited with code9009 in 0.655 seconds 想用vscode写个脚本,用自己电脑配置了下vscode的python环境,结果点击右上角三角图标运行时却只会输出exited with code9009 in 0.655 seconds 这就不太理解了,我在公司时是能正…

linux性能分析 性能之巅学习笔记和内容摘录

本文只是在阅读《性能之巅》的过程中,对一些觉得有用的地方进行的总结和摘录,并附加一些方便理解的材料,完整内容还请阅读Gregg的大作 概念和方法 性能分析领域一词的全栈代表了整个操作系统的软硬件在内的所有事物 软件生命周期和性能规划…

LabWindows CVI 2017开发笔记--串口API

参考资料:https://download.csdn.net/download/Stark_/87424565?spm1001.2014.3001.5501 转载请注明出处:https://blog.csdn.net/Stark_/article/details/128966962?spm1001.2014.3001.5501 打开串口OpenComConfig OpenComConfig 打开一个串行并进行…

HTML-CSS-js教程

HTML 双标签<html> </html> 单标签<img> html5的DOCTYPE声明 <!DOCTYPE html>html的基本骨架 <!DOCTYPE html> <html> </html>head标签 用于定义文档的头部。文档的头部包含了各种属性和信息&#xff0c;包括文档的标题&#…

【成为架构师课程系列】架构设计中的核心思维方法

架构设计中的核心思维方法 目录 前言 #一、抽象思维 #二、分层思维 #三、分治思维 #四、演化思维 #五、如何培养架构设计思维

leaflet 加载WKT数据(示例代码050)

第050个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载WKT文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共67行…

中国特色地流程管理系统,天翎让流程审批更简单

编者按&#xff1a;本文分析了国内企业在采购流程管理系统常遇到的一些难点&#xff0c;并从适应中国式流程管理模式的特点出发&#xff0c;介绍了符合中国特色的流程审批管理系统——天翎流程管理系统。关键词&#xff1a;可视化开发&#xff0c;拖拽建模&#xff0c;审批控制…

威联通ContainerStation部署Oracle11g

文章目录前言部署过程详解使用docker-compose文件创建容器临时开启NAS的SSH远程访问通过SSH客户端远程连接NAS进入容器创建用户拷贝容器中的数据库相关文件至宿主机在ContainerStation中修改docker-compose文件总结前言 ContainerStation本质上是对Docker可视化的一款软件&…

聊聊分布式锁——Redis和Redisson的方式

一、什么是分布式锁 分布式~~锁&#xff0c;要这么念&#xff0c;首先得是『分布式』&#xff0c;然后才是『锁』 分布式&#xff1a;这里的分布式指的是分布式系统&#xff0c;涉及到好多技术和理论&#xff0c;包括CAP 理论、分布式存储、分布式事务、分布式锁... 分布式系统…

Android开发

前言&#xff1a;因为这学期选了手机APP开发这门课&#xff0c;所以还是写个博客记录一下学习过程&#xff0c;包括安卓开发和ios开发。用到的资料包括课程PPT&#xff0c;和我在网上找的一些视频和资料。 1.Andriod入门 XML&#xff1a;描绘应用界面 &#xff08;决定APP长什…

NeurIPS/ICLR/ICML AI三大会国内高校和企业近年中稿量完整统计

点击文末公众号卡片&#xff0c;找对地方&#xff0c;轻松参会。 近日&#xff0c;有群友转发了一张网图&#xff0c;统计了近年来中国所有单位在NeurIPS、ICLR、ICML论文情况。原图如下&#xff1a; 中稿数100&#xff1a; 清华(1) 北大(2) 占比&#xff1a;22.6%。 累计数…

基于注解管理Bean

一、介绍从 Java 5 开始&#xff0c;Java 增加了对注解&#xff08;Annotation&#xff09;的支持&#xff0c;它是代码中的一种特殊标记&#xff0c;可以在编译、类加载和运行时被读取&#xff0c;执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下&#x…

全板电镀与图形电镀,到底有什么区别?

衔接上文&#xff0c;继续为朋友们分享普通单双面板的生产工艺流程。 如图&#xff0c;第四道主流程为电镀。 电镀的目的为&#xff1a; 适当地加厚孔内与板面的铜厚&#xff0c;使孔金属化&#xff0c;从而实现层间互连。 至于其子流程&#xff0c;可以说是非常简单&#x…

黑马】后台管理176-183

一、新建订单管理的分支二、创建一个订单管理的vue文件进行组件页面的路由配置import Order from ../components/order/Order.vue{path:/orders,component:Order},注意上面的components不要忘记少加一个s&#xff01;三&#xff0c;获取后台数据面包屑导航粘贴过来文本输入框&a…

手写MySQL补充章(十二)SQL语法解析之语法树

目录 模块分析 AST节点类型 SQL词法解析 举个例子 之前写的在第九章写的sql解析太简单了&#xff0c;SQL规范还有复杂的开闭括号以及嵌套查询&#xff0c;复杂SQL几乎不可能通过字符串匹配来实现。 本章以Druid SQL Parser解析SQL为例&#xff0c;进行分析。 模块分析 D…