上一篇文章:Python标准库---14、内置类型:二进制序列类型 (memoryview)
下一篇文章:Python标准库---16、内置类型:上下文管理器类型、其他、特殊属性
集合类型 --- set, frozenset
set 对象是由具有唯一性的 hashable 对象所组成的无序多项集。 常见的用途包括成员检测、从序列中去除重复项以及数学中的集合类计算,例如交集、并集、差集与对称差集等等。 (关于其他容器对象请参看 dict, list 与 tuple 等内置类,以及 collections 模块。)
与其他多项集一样,集合也支持 x in set, len(set) 和 for x in set。 作为一种无序的多项集,集合并不记录元素位置或插入顺序。 相应地,集合不支持索引、切片或其他序列类的操作。
目前有两种内置集合类型,set 和 frozenset。 set 类型是可变的 --- 其内容可以使用 add() 和 remove() 这样的方法来改变。 由于是可变类型,它没有哈希值,且不能被用作字典的键或其他集合的元素。 frozenset 类型是不可变并且为 hashable --- 其内容在被创建后不能再改变;因此它可以被用作字典的键或其他集合的元素。
除了可以使用 set 构造器,非空的 set (不是 frozenset) 还可以通过将以逗号分隔的元素列表包含于花括号之内来创建,例如: {'jack', 'sjoerd'}。
两个类的构造器具有相同的作用方式:
class set([iterable])
class frozenset([iterable])
返回一个新的 set 或 frozenset 对象,其元素来自于 iterable。 集合的元素必须为 hashable。 要表示由集合对象构成的集合,所有的内层集合必须为 frozenset 对象。 如果未指定 iterable,则将返回一个新的空集合。set 和 frozenset 的实例提供以下操作:
len(s)
返回集合 s 中的元素数量(即 s 的基数)。
### x in s
检测 x 是否为 s 中的成员。
### x not in s
检测 x 是否非 s 中的成员。
### isdisjoint(other)
如果集合中没有与 other 共有的元素则返回 True。 当且仅当两个集合的交集为空集合时,两者为不相交集合。
issubset(other)
set <= other
检测是否集合中的每个元素都在 other 之中。
### set < other
检测集合是否为 other 的真子集,即 set <= other and set != other。
issuperset(other)
set >= other
检测是否 other 中的每个元素都在集合之中。
### set > other
检测集合是否为 other 的真超集,即 set >= other and set != other。
union(*others)
set | other | ...
返回一个新集合,其中包含来自原集合以及 others 指定的所有集合中的元素。
intersection(*others)
set & other & ...
返回一个新集合,其中包含原集合以及 others 指定的所有集合中共有的元素。
### difference(*others)
### set - other - ...
返回一个新集合,其中包含原集合中在 others 指定的其他集合中不存在的元素。
### symmetric_difference(other)
### set ^ other
返回一个新集合,其中的元素或属于原集合或属于 other 指定的其他集合,但不能同时属于两者。
copy()
返回原集合的浅拷贝。请注意,非运算符版本的 union(), intersection(), difference(),以及 symmetric_difference(), issubset() 和 issuperset() 方法会接受任意可迭代对象作为参数。 相比之下,它们所对应的运算符版本则要求其参数为集合。 这就排除了容易出错的构造形式例如 set('abc') & 'cbs',而推荐可读性更强的 set('abc').intersection('cbs')。set 和 frozenset 均支持集合与集合的比较。 两个集合当且仅当每个集合中的每个元素均包含于另一个集合之内(即各为对方的子集)时则相等。 一个集合当且仅当其为另一个集合的真子集(即为后者的子集但两者不相等)时则小于另一个集合。 一个集合当且仅当其为另一个集合的真超集(即为后者的超集但两者不相等)时则大于另一个集合。set 的实例与 frozenset 的实例之间基于它们的成员进行比较。 例如 set('abc') == frozenset('abc') 返回 True,set('abc') in set([frozenset('abc')]) 也一样。子集与相等比较并不能推广为完全排序函数。 例如,任意两个非空且不相交的集合不相等且互不为对方的子集,因此以下 所有 比较均返回 False: a<b, a==b, or a>b。由于集合仅定义了部分排序(子集关系),因此由集合构成的列表 list.sort() 方法的输出并无定义。集合的元素,与字典的键类似,必须为 hashable。混合了 set 实例与 frozenset 的二进制位运算将返回与第一个操作数相同的类型。例如: frozenset('ab') | set('bc') 将返回 frozenset 的实例。下表列出了可用于 set 而不能用于不可变的 frozenset 实例的操作:
update(*others)
set |= other | ...
更新集合,添加来自 others 中的所有元素。
intersection_update(*others)
set &= other & ...
更新集合,只保留其中在所有 others 中也存在的元素。
difference_update(*others)
### set -= other | ...
更新集合,移除其中也存在于 others 中的元素。
### symmetric_difference_update(other)
### set ^= other
更新集合,只保留存在于集合的一方而非共同存在的元素。
add(elem)
将元素 elem 添加到集合中。
### remove(elem)
从集合中移除元素 elem。 如果 elem 不存在于集合中则会引发 KeyError。
### discard(elem)
如果元素 elem 存在于集合中则将其移除。
pop()
从集合中移除并返回任意一个元素。 如果集合为空则会引发 KeyError。
### clear()
从集合中移除所有元素。请注意,非运算符版本的 update(), intersection_update(), difference_update() 和 symmetric_difference_update() 方法将接受任意可迭代对象作为参数。请注意,__contains__(), remove() 和 discard() 方法的 elem 参数可能是一个 set。 为支持对一个等价的 frozenset 进行搜索,会根据 elem 临时创建一个该类型对象。
映射类型 --- dict
mapping 对象会将 hashable 值映射到任意对象。 映射属于可变对象。 目前仅有一种标准映射类型 字典。 (关于其他容器对象请参看 list, set 与 tuple 等内置类,以及 collections 模块。)
字典的键 几乎 可以是任何值。 非 hashable 的值,即包含列表、字典或其他可变类型的值(此类对象基于值而非对象标识进行比较)不可用作键。 数字类型用作键时遵循数字比较的一般规则:如果两个数值相等 (例如 1 和 1.0) 则两者可以被用来索引同一字典条目。 (但是请注意,由于计算机对于浮点数存储的只是近似值,因此将其用作字典键是不明智的。)
字典可以通过将以逗号分隔的 键: 值 对列表包含于花括号之内来创建,例如: {'jack': 4098, 'sjoerd': 4127} 或 {4098: 'jack', 4127: 'sjoerd'},也可以通过 dict 构造器来创建。
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
返回一个新的字典,基于可选的位置参数和可能为空的关键字参数集来初始化。如果没有给出位置参数,将创建一个空字典。 如果给出一个位置参数并且其属于映射对象,将创建一个具有与映射对象相同键值对的字典。 否则的话,位置参数必须为一个 iterable 对象。 该可迭代对象中的每一项本身必须为一个刚好包含两个元素的可迭代对象。 每一项中的第一个对象将成为新字典的一个键,第二个对象将成为其对应的值。 如果一个键出现一次以上,该键的最后一个值将成为其在新字典中对应的值。如果给出了关键字参数,则关键字参数及其值会被加入到基于位置参数创建的字典。 如果要加入的键已存在,来自关键字参数的值将替代来自位置参数的值。作为演示,以下示例返回的字典均等于 {"one": 1, "two": 2, "three": 3}:
>>> 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
像第一个例子那样提供关键字参数的方式只能使用有效的 Python 标识符作为键。 其他方式则可使用任何有效的键。这些是字典所支持的操作(因而自定义的映射类型也应当支持):
len(d)
返回字典 d 中的项数。
d[key]
返回 d 中以 key 为键的项。 如果映射中不存在 key 则会引发 KeyError。 如果字典的子类定义了方法 __missing__() 并且 key 不存在,则 d[key] 操作将调用该方法并附带键 key 作为参数。 d[key] 随后将返回或引发 __missing__(key) 调用所返回或引发的任何对象或异常。 没有其他操作或方法会发起调用 __missing__()。 如果未定义 __missing__(),则会引发 KeyError。 __missing__() 必须是一个方法;它不能是一个实例变量:
>>> class Counter(dict): ... def __missing__(self, key): ... return 0 >>> c = Counter() >>> c['red'] 0 >>> c['red'] += 1 >>> c['red'] 1
上面的例子显示了 collections.Counter 实现的部分代码。 还有另一个不同的 __missing__ 方法是由 collections.defaultdict 所使用的。
d[key] = value
将 d[key] 设为 value。
del d[key]
将 d[key] 从 d 中移除。 如果映射中不存在 key 则会引发 KeyError。
key in d
如果 d 中存在键 key 则返回 True,否则返回 False。
key not in d
等价于 not key in d。
iter(d)
返回以字典的键为元素的迭代器。 这是 iter(d.keys()) 的快捷方式。
clear()
移除字典中的所有元素。
### copy()
返回原字典的浅拷贝。
### classmethod fromkeys(iterable[, value])
使用来自 iterable 的键创建一个新字典,并将键值设为 value。 fromkeys() 属于类方法,会返回一个新字典。 value 默认为 None。
get(key[, default])
如果 key 存在于字典中则返回 key 的值,否则返回 default。 如果 default 未给出则默认为 None,因而此方法绝不会引发 KeyError。
### items()
返回由字典项 ((键, 值) 对) 组成的一个新视图。 参见 视图对象文档。
keys()
返回由字典键组成的一个新视图。 参见 视图对象文档。
pop(key[, default])
如果 key 存在于字典中则将其移除并返回其值,否则返回 default。 如果 default 未给出且 key 不存在于字典中,则会引发 KeyError。
popitem()
从字典中移除并返回一个 (键, 值) 对。 键值对会按 LIFO 的顺序被返回。 popitem() 适用于对字典进行消耗性的迭代,这在集合算法中经常被使用。 如果字典为空,调用 popitem() 将引发 KeyError。 在 3.7 版更改: 现在会确保采用 LIFO 顺序。 在之前的版本中,popitem() 会返回一个任意的键/值对。
setdefault(key[, default])
如果字典存在键 key ,返回它的值。如果不存在,插入值为 default 的键 key ,并返回 default 。 default 默认为 None。
update([other])
使用来自 other 的键/值对更新字典,覆盖原有的键。 返回 None。 update() 接受另一个字典对象,或者一个包含键/值对(以长度为二的元组或其他可迭代对象表示)的可迭代对象。 如果给出了关键字参数,则会以其所指定的键/值对更新字典: d.update(red=1, blue=2)。
values()
返回由字典值组成的一个新视图。 参见 视图对象文档。两个字典的比较当且仅当具有相同的 (键, 值) 对时才会相等。 顺序比较 ('<', '<=', '>=', '>') 会引发 TypeError。
字典会保留插入时的顺序。 请注意对键的更新不会影响顺序。 删除并再次添加的键将被插入到末尾。
>>> d = {"one": 1, "two": 2, "three": 3, "four": 4} >>> d {'one': 1, 'two': 2, 'three': 3, 'four': 4} >>> list(d) ['one', 'two', 'three', 'four'] >>> list(d.values()) [1, 2, 3, 4] >>> d["one"] = 42 >>> d {'one': 42, 'two': 2, 'three': 3, 'four': 4} >>> del d["two"] >>> d["two"] = None >>> d {'one': 42, 'three': 3, 'four': 4, 'two': None}
在 3.7 版更改: 字典顺序会确保为插入顺序。 此行为是自 3.6 版开始的 CPython 实现细节。
参见
types.MappingProxyType 可被用来创建一个 dict 的只读视图。
字典视图对象
由 dict.keys(), dict.values() 和 dict.items() 所返回的对象是 视图对象。 该对象提供字典条目的一个动态视图,这意味着当字典改变时,视图也会相应改变。
字典视图可以被迭代以产生与其对应的数据,并支持成员检测:
len(dictview)
返回字典中的条目数。
iter(dictview)
返回字典中的键、值或项(以 (键, 值) 为元素的元组表示)的迭代器。键和值是按插入时的顺序进行迭代的。 这样就允许使用 zip() 来创建 (值, 键) 对: pairs = zip(d.values(), d.keys())。 另一个创建相同列表的方式是 pairs = [(v, k) for (k, v) in d.items()].在添加或删除字典中的条目期间对视图进行迭代可能引发 RuntimeError 或者无法完全迭代所有条目。在 3.7 版更改: 字典顺序会确保为插入顺序。
x in dictview
如果 x 是对应字典中存在的键、值或项(在最后一种情况下 x 应为一个 (键, 值) 元组) 则返回 True。
键视图类似于集合,因为其条目不重复且可哈希。 如果所有值都是可哈希的,即 (键, 值) 对也是不重复且可哈希的,那么条目视图也会类似于集合。 (值视图则不被视为类似于集合,因其条目通常都是有重复的。) 对于类似于集合的视图,为抽象基类 collections.abc.Set 所定义的全部操作都是有效的 (例如 ==, < 或 ^)。
一个使用字典视图的示例:
>>>>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}>>> keys = dishes.keys()>>> values = dishes.values()>>> # iteration>>> n = 0>>> for val in values:... n += val>>> print(n)504>>> # keys and values are iterated over in the same order (insertion order)>>> list(keys)['eggs', 'sausage', 'bacon', 'spam']>>> list(values)[2, 1, 1, 500]>>> # view objects are dynamic and reflect dict changes>>> del dishes['eggs']>>> del dishes['sausage']>>> list(keys)['bacon', 'spam']>>> # set operations>>> keys & {'eggs', 'bacon', 'salad'}{'bacon'}>>> keys ^ {'sausage', 'juice'}{'juice', 'sausage', 'bacon', 'spam'}
上一篇文章:Python标准库---14、内置类型:二进制序列类型 (memoryview)
下一篇文章:Python标准库---16、内置类型:上下文管理器类型、其他、特殊属性