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 中的所有元素
  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/christal-11/p/7678033.html
Copyright © 2011-2022 走看看