【流畅的python】笔记(C3字典和集合)自测知识点和书籍补充

    技术2022-07-12  81

    文章目录

    C3 字典和集合3.1 泛映射类型自测答案 3.2 字典推导自测答案 3.3 常见的映射方法自测答案 3.4 映射的弹性键查询自测答案 3.4.1  defaultdict :处理找不到的键的一个选择自测答案 3.4.2 特殊方法 __missing__自测答案 3.5 字典的变种自测答案 3.6 子类化 UserDict自测答案 3.7 不可变映射类型自测答案 3.8 集合论自测答案 3.8.1 集合字面量自测答案

    C3 字典和集合

    3.1 泛映射类型

    自测

    1.Python 里所有的不可变类型都是可散列的吗?

    答案

    1. 否,比如虽然元组本身是不可变序列,它里面的元素可能是其他可变类型的引用。如果元组的元素每个值都是可散列情况下那元组本身就是可散列的。

    对于容器,可散列不仅需要对本身散列还需要内部元素也散列。对于非容器只需要本身满足不可变类型即是可散列的

    3.2 字典推导

    自测

    1.用字典推导式完成缺失的代码?

    答案

    1. 字典推导式和列表推导式写法很类似

    3.3 常见的映射方法

    自测

    1.什么时候你会用setdefault, 什么时候用get?

    答案

    1. setdefault是字典对象的一个实例方法,接收两个参数,用法和字典的get方法类似,但是比 get 更强大。 它可以为给字典的key设定一个默认值(如果key不在字典中的时候)get 方法设置的默认值不会改变原字典, 而setdefault设置的默认值会改变原字典的值。

    所以,如果你想做的事情是“查找来插入新值” 请用setdefault。否则两种无异

    3.4 映射的弹性键查询

    自测

    1.单纯地查找字典的键,取值怎么处理找不到的情况呢?

    答案

    1. 一个是通过 defaultdict 这个类型而不是普通的 dict ,另一个是给自己定义一个 dict 的子类,然后在子类中实现__missing__ 方法。

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

    自测

    1.单纯地查找字典的键,取值怎么处理找不到的情况呢?

    答案

    1. 一个是通过 defaultdict 这个类型而不是普通的 dict ; 另一个是给自己定义一个 dict 的子类,然后在子类中实现__missing__ 方法。

    3.4.2 特殊方法 missing

    自测

    1.什么时候会触发__missing__?

    答案

    1. __missing__ 方法只会被 __getitem__ 调用(比如在表达式 d[k] 中)。提供__missing__方法对 get 或者 __contains__ ( in 运算符会用到这个方法)这些方法的使用没有影响。 但是我们从 dict 继承到的__contains__ 方法不会在找不到键的时候调用 __missing__方法。

    3.5 字典的变种

    自测

    1.OrderedDict作用? 2.ChainMap作用? 3.Counter作用?

    答案

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

    2. 该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。这个功能在给有嵌套作用域的语言做解 释器的时候很有用,可以用一个映射对象来代表一个作用域的上下文。

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

    3.6 子类化 UserDict

    自测

    1.更倾向于从 UserDict 而不是从 dict 继承的主要原因?

    答案

    1. 后者有时会在某些方法的实现上走一些捷径,导致我们不得不在它的子类中重写这些方法,但是 UserDict 就不会带来这些问题。 UserDict 并不是 dict 的子类,但是 UserDict 有一个叫作data 的属性,是 dict 的实例,这个属性实际上是 UserDict 最终存储数据的地方。

    3.7 不可变映射类型

    自测

    1.实现方式? 1.作用?

    答案

    1. 使用types 模块中引入了一个封装类名叫 MappingProxyType。 2. 如果给这个类一个映射,它会返回一个只读的映射视图。虽然是个只读视图,但是它是动态的。这意味着如果对原映射做出了改动,我们通过这个视图可以观察到,但是无法通过这个视图对原映射做出修改。

    3.8 集合论

    自测

    1.集合里存储的是什么? 2.集合的元素必须是可散列的吗?

    答案

    1. 集合的存储是许多唯一对象的聚集。因此,集合可以用于去重

    2. 集合中的元素必须是可散列的(不是散列的,人家怎么去重呢!), set 类型本身是不可散列的,但是 frozenset 可以容纳不是可散列的对象。因此可以创建一个包含不同 frozenset 的 set 。

    3.8.1 集合字面量

    自测

    1.易错:创建空集合是写成{}还是set() ? 2. 创建集合123,哪一种方式更快?{1, 2, 3}还是 set([1, 2, 3]) )

    答案

    1. 如果要创建一个空集,你必须用不带任何参数的构造方法 set() 。如果只是写成 {} 的形式,跟以前一样,你创建的其实是个空字典。

    2. 像 {1, 2, 3} 这种字面量句法相比于构造方法( set([1, 2, 3]) )要更快且更易读。后者的速度要慢一些,因为 Python 必须先从 set 这个名字来查询构造方法,然后新建一个列表,最后再把这个列表传入到构造方法里。但是如果是像 {1, 2, 3} 这样的字面量,Python 会利用一个专门的叫作 BUILD_SET 的字节码来创建集合。

    Processed: 0.052, SQL: 9