zoukankan      html  css  js  c++  java
  • python 核心编程(第二版)——映射和集合类型

    字典是Python 语言中唯一的映射类型。映射类型对象里哈希值(键) 和指向的对象(值)是一对多的关系。一个字典对象是可变的,它是一个容器类型,能存储任意个数的Python 对象,其中也包括其他容器类型。字典类型和序列类型容器类(列表、元组)的区别是存储和访问数据的方式不同。序列类型只用数字类型的键(从序列的开始起按数值顺序索引)。映射类型可以用其他对象类型做键;一般最常见的是用字符串做键(keys)。和序列类型的键不同,映射类型的键(keys)直接,或间接地和存储的数据值相关联。但因为在映射类型中,我们不再用"序列化排序"的键(keys),所以映射类型中的数据是无序排列的。

    核心笔记:什么是哈希表?它们与字典的关系是什么?

    序列类型用有序的数字键做索引将数据以数组的形式存储。一般,索引值与所存储的数据毫无关系。还可以用另一种方式来存储数据:基于某种相关值,比如说一个字符串。哈希表是一种数据结构:它按照我们所要求的去工作。哈希表中存储的每一条数据,叫做一个值(value),是根据与它相关的一个被称作为键(key)的数据项进行存储的。键和值合在一起被称为“键-值 对”(key-value pairs)。 哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果,选择在数据结构的某个地址中来存储你的值。任何一个值存储的地址皆取决于它的键。正因为这种随意性,哈希表中的值是没有顺序的。你拥有的是一个无序的数据集。

    你所能获得的有序集合只能是字典中的键的集合或者值的集合。方法Keys() 或 values() 返回一个列表,该列表是可排序的。 你还可以用 items()方法得到包含键、值对的元组的列表来排序。由于字典本身是哈希的,所以是无序的。哈希表一般有很好的性能, 因为用键查询相当快。

    一个字典条目的语法格式是 键:值。 而且,多条字典条目被包含在( { } ) 里。创建字典只需要把字典赋值给一个变量,不管这个字典是否包含元素。

    从Python 2.2 版本起, 可以用工厂方法 dict() 来创建字典;

    从Python 2.3 版本起, 可以用一个很方便的内建方法fromkeys() 来创建一个"默认"字典, 字典中元素具有相同的值 (如果没有给出, 默认为None)。如:ddict = {}.fromkeys(('x', 'y'), -1);

    要想遍历一个字典(一般用键), 你只需要循环查看它的键,ex:for key in dict2.keys();从Python 2.2开始,可以用迭代器来访问类序列对象,ex:for key in dict2(dict2为创建的字典);

    要得到字典中某个元素的值, 可以用你所熟悉的字典键加上中括号来得到:ex dict2[‘name’];

    检查一个字典中是否有某个键的最好方法是in 或 not in 操作符。

    更新字典:可以通过以下几种方式对一个字典做修改:

    (1)添加一个新数据项或新元素(即,一个键-值对);

    (2)修改一个已存在的数据项;

    (3)或删除一个已存在的数据项。

    1 >>> dict2['name'] = 'venus' # 更新已有条目
    2 >>> dict2['port'] = 6969 # 更新已有条目
    3 >>> dict2['arch'] = 'sunos5'# 增加新条目
    4 >>>
    5 >>> print 'host %(name)s is running on port %(port)d' %dict2
    6 host venus is running on port 6969
    View Code

    上面的print 语句展示了另一种在字典中使用字符串格式符( %)的方法。用字典参数可以简化print 语句,因为这样做你只须用到一次该字典的名字,而不用在每个元素出现的时候都用元组参数表示。

    你也可以用内建方法update()将整个字典的内容添加到另一个字典。

    删除整个字典的操作不常见。通常,你删除字典中的单个元素或是清除整个字典的内容。但是,
    如果你真想"删除"一个字典,用del 语句

     删除字典元素与字典:删除整个字典的操作不常见。通常,你删除字典中的单个元素或是清除整个字典的内容。但是,如果你真想"删除"一个字典,用del 语句

    1 del dict2['name'] # 删除键为“name”的条目
    2 dict2.clear() # 删除dict2 中所有的条目
    3 del dict2 # 删除整个dict2 字典
    4 dict2.pop('name') # 删除并返回键为“name”的条目
    View Code

    核心笔记:避免使用内建对象名字作为变量的标识符?

    如果在Python 2.3 前,你已经开始使用Python,你可能用dict 作为一个字典的标识符。但是,因为 dict() 现在已成为 Python 的类型和工厂方法,重载dict()会给你带来麻烦和潜在的bugs。编译器允许你做这样的重载,它认为你是聪明的,知道自己正在做什么!小心。请不要用 dict, list,file, bool, str, input, len 这样的内建类型为变量命名。

    2.映射类型操作符

    字典可以和所有的标准类型操作符一起工作,但却不支持像拼接(concatenation)和重复(repetition)这样的操作。这些操作对序列有意义,可对映射类型行不通。

    字典的键查找操作符([ ]):键查找操作符是唯一仅用于字典类型的操作符,对字典类型来说,是用键(key)查询(字典中的元素),所以键是参数(argument), 而不是一个索引(index)。键查找操作符既可以用于给字典赋值,也可以用于从字典中取值:

    d[k] = v 通过键'k',给字典中某元素赋值'v'
    d[k] 通过键'k',查询字典中某元素的值

    (键)成员关系操作( in ,not in):用 in 和 not in 操作符来检查某个键是否存在于字典中。

    3.映射类型的内建函数和工厂函数

    标准类型函数[type()、str()和cmp()]:对一个字典调用type()工厂方法,会返回字典类型;调用str()工厂方法将返回该字典的字符串表示形式;调用cmp()工厂方法来比较字典,首先是字典的大小,然后是键,最后是值。

    cmp()可以返回除-1,0,1 外的其他值。算法按照以下的顺序:

    1)、比较字典长度——字典中的键的个数越多,这个字典就越大

    2)、比较字典的键——如果两个字典的长度相同,那就按字典的键比较;键比较的顺序和 keys()方法返回键的顺序相同。

    3)、比较字典的值——如果两个字典的长度相同而且它们的键也完全匹配,则用字典中每个相同的键所对应的值进行比较。

    4)、Exact Match——若每个字典有相同的长度、相同的键、每个键也对应相同的值,则字典完全匹配,返回0 值。

    映射类型相关的函数:

    dict()——创建字典的工厂函数。如果不提供参数,会生成空字典。当容器类型对象做为一个参数传递给方法dict() 时很有意思。如果参数是可以迭代的,即,一个序列,或是一个迭代器,或是一个支持迭代的对象,那每个可迭代的元素必须成对出现。在每个值对中,第一个元素是字典的键、第二个元素是字典中的值。

    如果输入参数是(另)一个映射对象,比如,一个字典对象,对其调用dict()会从存在的字典里复制内容来生成新的字典。新生成的字典是原来字典对象的浅复制版本, 它与用字典的内建方法copy() 生成的字典对象是一样的。但是从已存在的字典生成新的字典速度比用copy()方法慢,推荐使用copy()。

    len()——返回映射的长度(键-值对的个数)。可用在序列、映射类型和集合上,对字典调用len(),它会返回所有元素(键-值对)的数目。

    hash()——返回obj 的哈希值。内建函数hash()本身并不是为字典设计的方法,但它可以判断某个对象是否可以做一个字典的键。将一个对象作为参数传递给 hash(), 会返回这个对象的哈希值。 只有这个对象是可哈希的,才可作为字典的键 (函数的返回值是整数,不产生错误或异常)。

    如果用比较操作符来比较两个数值,发现它们是相等的,那么即使二者的数据类型不同, 它们也会得到相同的哈希值。

    如果非可哈希类型作为参数传递给hash()方法,会产生TypeError 错误(因此,如果使用这样的对象作为键给字典赋值时会出错)。

    4.映射类型内建方法

    字典类型方法
    方法名字 操作
    dict.clear() 删除字典中所有元素
    dict.copy() 返回字典(浅复制)的一个副本

    dict.fromkeys(seq,

    val=None)

    创建并返回一个新字典,以seq 中的元素做该字典的键,val 做该字典中所有键对应的初始值(如果不提供此值,则默认为None)

    dict.get(key,
    default=None)

    对字典dict 中的键key,返回它对应的值value,如果字典中不存在此键,则返回default 的值(注意,参数default 的默认值为None)

    dict.has_key(key)

    如果键(key)在字典中存在,返回True,否则返回False. 在Python2.2版本引入in 和not in 后,此方法几乎已废弃不用了,但仍提供一个可工作的接口。

    dict.items() 返回一个包含字典中(键, 值)对元组的列表
    dict.keys() 返回一个包含字典中键的列表
    dict.iter()

    方法iteritems(), iterkeys(), itervalues()与它们对应的非迭代方法一样,不同的是它们返回一个迭代子,而不是一个列表。

    dict.pop(key
    [, default])

    和方法get()相似,如果字典中key 键存在,删除并返回dict[key],如果key 键不存在,且没有给出default 的值,引发KeyError 异常。

    dict.setdefault(key,
    default=None)

    和方法set()相似,如果字典中不存在key 键,由dict[key]=default 为它赋值。

    dict.update(dict2) 将字典dict2 的键-值对添加到字典dict
    dict.values() 返回一个包含字典中所有值的列表

    基本的字典方法关注他们的键和值。它们有:keys()方法,返回一个列表,包含字典中所有的键,values()方法,返回一个列表,包含字典中所有的值,items(), 返回一个包含所有(键, 值)元组的列表。这些方法不按任何顺序遍历字典的键或值时很有用。

    keys()方法很有用,它返回一个包含字典中所有键的列表,此方法可以与for 循环一起使用来获取字典中的值。但是,它返回的元素是没有顺序的(和哈希表中的键(keys)一样)。若想按照某种方式排序,即可使用python2.4版本特别为迭代子设计了一个名为 sorted(字典名)的内建函数,它返回一个有序的迭代子。

    sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list

    iterable:是可迭代类型;
    cmp:用于比较的函数,比较什么由key决定;
    key:用列表元素的某个属性或函数进行作为关键字,有默认值,迭代集合中的一项;
    reverse:排序规则. reverse = True  降序 或者 reverse = False 升序,有默认值。
    返回值:是一个经过排序的可迭代类型,与iterable一样。

    注:一般来说,cmp 和 key 可以使用 lambda表达式。

    1 for eachKey in sorted(dict2):
    2 ... print 'dict2 key', eachKey, 'has value',
    3 dict2[eachKey]
    4 ...
    5 dict2 key name has value earth
    6 dict2 key port has value 80
    View Code

    update()方法可以用来将一个字典的内容添加到另外一个字典中。字典中原有的键如果与新添加的键重复,那么重复键所对应的原有条目的值将被新键所对应的值所覆盖。原来不存在的条目则被添加到字典中。clear()方法可以用来删除字典中的所有的条目。

    copy() 方法返回一个字典的副本。注意这只是浅复制。

    get()方法和键查找(key-lookup)操作符( [ ] )相似,不同的是它允许你为不存在的键提供默认值。如果该键不存在,也未给出它的默认值,则返回None。此方法比采用键查找(key-lookup)更灵活,因为你不必担心因键不存在而引发异常。

    setdefault()是自 2.0 才有的内建方法, 使得代码更加简洁,它实现了常用的语法: 检查字典中是否含有某键。 如果字典中这个键存在,你可以取到它的值。 如果所找的键在字典中不存在,你可以给这个键赋默认值并返回此值。

     1 >>> myDict = {'host': 'earth', 'port': 80}
     2 >>> myDict.keys()
     3 ['host', 'port']
     4 >>> myDict.items()
     5 [('host', 'earth'), ('port', 80)]
     6 >>> myDict.setdefault('port', 8080)
     7 >>> myDict.setdefault('prot', 'tcp')
     8 'tcp'
     9 >>> myDict.items()
    10 [('prot', 'tcp'), ('host', 'earth'), ('port', 80)]
    11 >>> {}.fromkeys('xyz')
    12 {'y': None, 'x': None, 'z': None}
    13 >>>
    14 >>> {}.fromkeys(('love', 'honor'), True)
    15 {'love': True, 'honor': True}
    View Code

    keys(), items(), 和 values()方法的返回值都是列表。数据集如果很大会导致很难处理,这也正是iteritems(), iterkeys(), 和itervalues() 方法被添加到 Python 2.2 的主要原因。这些函数与返回列表的对应方法相似,只是它们返回惰性赋值的迭代器,所以节省内存。

    5.字典的键

    字典中的值没有任何限制。 他们可以是任意Python 对象,即,从标准对象到用户自定义对象皆可。但是字典中的键是有类型限制的。

    必须明确一条原则:每个键只能对应一个项。也就是说,一键对应多个值是不允许的。(像列表、元组和其他字典这样的容器对象是可以的。) 当有键发生冲突(即,字典键重复赋值),取最后(最近)的赋值。

    Python 并不会因字典中的键存在冲突而产生一个错误,它不会检查键的冲突是因为,如果真这样做的话,在每个键-值对赋值的时候都会做检查,这将会占用一定量的内存。

    所有不可变的类型都是可哈希的,因此它们都可以做为字典的键。一个要说明的是问题是数字:值相等的数字表示相同的键。换句话来说,整型数字 1 和 浮点数 1.0 的哈希值是相同的,即它们是相同的键。

    为什么键必须是可哈希的?——解释器调用哈希函数,根据字典中键的值来计算存储你的数据的位置。如果键是可变对象,它的值可改变。如果键发生变化,哈希函数会映射到不同的地址来存储数据。如果这样的情况发生,哈希函数就不可能可靠地存储或获取相关的数据。选择可哈希的键的原因就是因为它们的值不能改变。

    数字和字符串可以被用做字典的键,但若用元组做有效的键,必须要加限制:元组中只包括像数字和字符串这样的不可变参数,才可以作为字典中有效的键。

     6.集合类型

    集合对象是一组无序排列的可哈希的值。集合支持用 in 和 not in 操作符检查成员, 由 len() 内建函数得到集合的基数(大小), 用for 循环迭代集合的成员。但是因为集合本身是无序的,你不可以为集合创建索引或执行切片(slice)操作,也没有键(keys)可用来获取集合中元素的值。

    集合(sets)有两种不同的类型,可变集合(set) 和 不可变集合(frozenset)。对可变集合(set),你可以添加和删除元素,对 不可变集合(frozenset)则不允许这样做。请注意,可变集合(set)不是可哈希的,因此既不能用做字典的键也不能做其他集合中的元素。不可变集合(frozenset)则正好相反,即,他们有哈希值,能被用做字典的键或是作为集合中的一个成员。

    集合操作符和关系符号
    数学符号 Python 符号 说明

    如何创建集合类型和给集合赋值?

    集合被创建的唯一方法 - 用集合的工厂方法 set()和 frozenset()。

     1 >>> s = set('cheeseshop')
     2 >>> s
     3 set(['c', 'e', 'h', 'o', 'p', 's'])
     4 >>> t = frozenset('bookshop')
     5 >>> t
     6 frozenset(['b', 'h', 'k', 'o', 'p', 's'])
     7 >>> type(s)
     8 <type 'set'>
     9 >>> type(t)
    10 <type 'frozenset'>
    11 >>> len(s)
    12 6
    13 >>> len(s) == len(t)
    14 True
    15 >>> s == t
    16 False
    View Code

    如何访问集合中的值?

    可以遍历查看集合成员或检查某项元素是否是一个集合中的成员。

     1 >>> 'k' in s
     2 False
     3 >>> 'k' in t
     4 True
     5 >>> 'c' not in t
     6 True
     7 >>> for i in s:
     8 ... print i
     9 ...
    10 c
    11 e
    12 h
    13 o
    14 p
    15 s
    View Code

    如何更新集合?

    用各种集合内建的方法和操作符添加和删除集合的成员。只有可变集合能被修改。试图修改不可变集合会引发异常。

     1 >>> s.add('z')
     2 >>> s
     3 set(['c', 'e', 'h', 'o', 'p', 's', 'z'])
     4 >>> s.update('pypi')
     5 >>> s
     6 set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y', 'z'])
     7 >>> s.remove('z')
     8 >>> s
     9 set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
    10 >>> s -= set('pypi')
    11 >>> s
    12 set(['c', 'e', 'h', 'o', 's'])
    View Code

    如何删除集合中的成员和集合?

    如果如何删除集合本身,可以像删除任何Python 对象一样,令集合超出它的作用范围,或调用del 将他们直接清除出当前的名字空间。如果它的引用计数为零,也会被标记以便被垃圾回收。

    7.集合类型操作符

    成员关系 (in, not in)——就序列而言,Python 中的in 和not in 操作符决定某个元素是否是一个集合中的成员。

    集合等价/不等价——等价/不等价被用于在相同或不同的集合之间做比较。两个集合相等是指,对每个集合而言,当且仅当其中一个集合中的每个成员同时也是另一个集合中的成员。也可以说每个集合必须是另一个集合的一个子集, 即,s <= t 和 s >= t 的值均为真(True),或(s <= t and s>= t) 的值为真(True)。集合等价/不等价与集合的类型或集合成员的顺序无关,只与集合的元素有关。

    子集/超集——Sets 用Python 的比较操作符检查某集合是否是其他集合的超集或子集。“小于”符号( <, <= )用来判断子集,“大于”符号( >, >= )用来判断超集。等于号允许非严格定义的子集和超集。

    Sets 支持严格( < )子集和非严格 ( <= ) 子集, 也支持严格( > )超集和非严格 ( >= )超集。只有当第一个集合是第二个集合的严格子集时,我们才称第一个集合“小于”第二个集合,同理,只有当第一个集合是第二个集合的严格超集时,我们才称第一个集合“大于”第二个集合。

    1 >>> set('shop') < set('cheeseshop')
    2 True
    3 >>> set('bookshop') >= set('shop')
    4 True
    View Code

    联合( | )——联合(union)操作和集合的OR(又称可兼析取(inclusive disjunction))其实是等价的,两个集合的联合是一个新集合,该集合中的每个元素都至少是其中一个集合的成员,即,属于两个集合其中之一的成员。联合符号有一个等价的方法,union()。

    交集( & )——交集操作比做集合的AND(或合取)操作。两个集合的交集是一个新集合,该集合中的每个元素同时是两个集合中的成员,即,属于两个集合的成员。交集符号有一个等价的方法,intersection()。

    差补/相对补集( – )——两个集合(s 和t)的差补或相对补集是指一个集合C,该集合中的元素,只属于集合s,而不属于集合t。差符号有一个等价的方法,difference()。

    对称差分( ^ )——对称差分是集合的XOR(又称”异或“ (exclusive disjunction)).两个集合(s 和t)的对称差分是指另外一个集合C,该集合中的元素,只能是属于集合s 或者集合t的成员,不能同时属于两个集合。对称差分有一个等价的方法,symmetric_difference()。

    混合集合类型操作——如果左右两个操作数的类型相同,既都是可变集合或不可变集合, 则所产生的结果类型是相同的,但如果左右两个操作数的类型不相同(左操作数是set,右操作数是frozenset,或相反情况),则所产生的结果类型与左操作数的类型相同。

    注意:加号不是集合类型的运算符。

    仅适用于可变集合:

    1)、(Union) Update ( |= ),这个更新方法从已存在的集合中添加(可能多个)成员,此方法和update()等价。

    1 >>> s = set('cheeseshop')
    2 >>> u = frozenset(s)
    3 >>> s |= set('pypi')
    4 >>> s
    5 set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
    View Code

    2)、保留/交集更新( &= ),保留(或交集更新)操作保留与其他集合的共有成员。此方法和intersection_update()等价。

    3)、差更新 ( –= ),差更新操作会返回一个集合,该集合中的成员是集合s 去除掉集合t 中元素后剩余的元素。此方法和difference_update()等价。

    4)、对称差分更新( ^= ),对称差分更新操作会返回一个集合,该集合中的成员仅是原集合s 或仅是另一集合t 中的成员。此方法和symmetric_difference_update()等价。

    8.内建函数

    len()——把集合作为参数传递给内建函数len(),返回集合的基数(或元素的个数)。

    set() and frozenset()——set()和frozenset()工厂函数分别用来生成可变和不可变的集合。如果不提供任何参数,默认会生成空集合。如果提供一个参数,则该参数必须是可迭代的,即,一个序列,或迭代器,或支持迭代的一个对象,例如:一个文件或一个字典。

     1 >>> set()
     2 set([])
     3 >>> set([])
     4 set([])
     5 >>> set(())
     6 set([])
     7 >>> set('shop')
     8 set(['h', 's', 'o', 'p'])
     9 >>>
    10 >>> frozenset(['foo', 'bar'])
    11 frozenset(['foo', 'bar'])
    12 >>>
    13 >>> f = open('numbers', 'w')
    14 >>> for i in range(5):
    15 ... f.write('%d
    ' % i)
    16 ...
    17 >>> f.close()
    18 >>> f = open('numbers', 'r')
    19 >>> set(f)
    20 set(['0
    ', '3
    ', '1
    ', '4
    ', '2
    '])
    21 >>> f.close()
    View Code

    9.集合类型内建方法

    集合类型方法
    方法名称 操作
    s.issubset(t) 如果s 是t 的子集,则返回True,否则返回False
    s.issuperset(t) 如果t 是s 的超集,则返回True,否则返回False
    s.union(t) 返回一个新集合,该集合是s 和t 的并集
    s.intersection(t) 返回一个新集合,该集合是s 和t 的交集
    s.difference(t) 返回一个新集合,该集合是s 的成员,但不是t 的成员
    s.symmetric_difference(t)

    返回一个新集合,该集合是s 或t 的成员,但不是s 和t 共有的成员

    s.copy() 返回一个新集合,它是集合s 的浅复制
    可变集合类型的方法
    方法名 操作
    s.update(t) 用t 中的元素修改s, 即,s 现在包含s 或t 的成员
    s.intersection_update(t) s 中的成员是共同属于s 和t 的元素。
    s.difference_update(t) s 中的成员是属于s 但不包含在t 中的元素
    s.symmetric_difference_update(t)

    s 中的成员更新为那些包含在s 或t 中,但不是s
    和t 共有的元素

    s.add(obj) 在集合s 中添加对象obj
    s.remove(obj)

    从集合s 中删除对象obj;如果obj 不是集合s 中的元素(obj not in s),将引发KeyError 错误

    s.discard(obj) 如果obj 是集合s 中的元素,从集合s 中删除对象obj;
    s.pop() 删除集合s 中的任意一个对象,并返回它
    s.clear() 删除集合s 中的所有元素

    10.操作符、函数/方法

    集合类型操作符、函数和方法
    函数、方法名所有集合类型 等价运算符 说明
    len(s)    
    set([obj])    
    frozenset([obj])

    obj in s

    obj not in s

    s == t

    s != t

    s < t

    不可变集合工厂函数; 执行方式和set()方法相同,但它返回的是不可变集合

    成员测试:obj 是s 中的一个元素吗?

    非成员测试:obj 不是s 中的一个元素吗?

    等价测试: 测试s 和t 是否具有相同的元素?

    不等价测试: 与==相反

    (严格意义上)子集测试; s != t 而且s 中 所 有的元素都是t 的成员

    s.issubset(t)

    s <= t

    s > t

    s >= t

    子集测试(允许不严格意义上的子集): s 中所有的元素都是t 的成员

    (严格意义上)超集测试: s != t 而且t 中所有的元素都是s 的成员

    超集测试(允许不严格意义上的超集): t 中所有的元素都是s 的成员

    s.union(t) s | t 合并操作:s 或t 中的元素
    s.intersec- tion(t) s & t 交集操作:s 和t 中的元素
    s.difference(t) s - t 差分操作: s 中的元素,而不是t 中的元素
    s.symmetric_difference(t) s ^ t

    对称差分操作:s 或t 中的元素,但不是s 和t 共有的元素

    s.copy()   复制操作:返回s 的(浅复制)副本
    集合类型,函数/方法(仅可变集合)
    函数/方法名字 操作符 等价描述
    s.update(t) s |= t (Union) 修改操作: 将t 中的成员添加s
    s.intersection_update(t) s &= t 交集修改操作: s 中仅包括s 和t 中共有的成员
    s.difference_update(t) s -= t 差修改操作: s 中包括仅属于s 但不属于t 的成员
    s.symmetric_ s ^= t

    对称差分修改操作: s 中包括仅属于s 或仅属于t 的
    成员

    difference_
    update(t)
    s.add(obj)   加操作: 将obj 添加到s
    s.remove(obj)  

    删除操作: 将obj 从s 中删除;如果s 中不存在obj,将引发KeyError

    s.discard(obj)  

    丢弃操作: remove() 的 友 好 版 本 - 如果 s 中存在obj,
    从s 中删除它

    s.pop()   Pop 操作: 移除并返回s 中的任意一个元素
    s.clear()   清除操作: 移除s 中的所有元素
  • 相关阅读:
    Vue3手册译稿
    捉虫日记 | MySQL 5.7.20 try_acquire_lock_impl 异常导致mysql crash
    window资源管理器无反应,右键转圈圈
    二、DHCP原理简介
    一、以太网协议
    FreeRTOS系统环境下,全局变量频繁同时在不同任务改写也可能导致硬件中断(HardFault)
    查找生成文件的进程
    解决docker容器无法访问宿主机网络的问题
    TiDB在更新版本的时候初始化Prometheus的配置文件失败
    好喜欢lodop的介绍
  • 原文地址:https://www.cnblogs.com/christal-11/p/7678033.html
Copyright © 2011-2022 走看看