集合和字典
上文说完了列表和元组,本文继续介绍另外两种常用的数据结构,集合和字典。
集合 set
集合是由不重复元素组成的无序容器。
Python中的集合和数学上的集合概念基本相同,也可以求交集、并集、差集等操作。
参考手册:“set 对象是由具有唯一性的 hashable 对象所组成的无序多项集。”
集合的创建
创建集合用花括号或 set
函数。更常见的是用集合推导式。
注意,创建空集合只能用 set()
,不能用 {}
,{}
创建的是空字典。
集合创建方法:
- 使用花括号内以逗号分隔元素的方式:
{'jack', 'sjoerd'}
- 使用集合推导式:
{c for c in 'abracadabra' if c not in 'abc'}
- 使用类型构造器:
set()
,set('foobar')
,set(['a', 'b', 'foo'])
集合的应用
集合具有不重复的性质,可以用来去重。
也可以用它的运算**差**a-b
、交a & b
、并a | b
、对称差a ^ b
。
注:对称差,等价于(a | b) - (a&b),即a与b的并集减去a与b的交集。
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'} print(basket) # 重复元素被去除 'orange' in basket # 支持 in 'crabgrass' in basket # 集合间的运算: a = set('abracadabra') b = set('alacazam') a # unique letters in a a - b # letters in a but not in b a | b # letters in a or b or both a & b # letters in both a and b a ^ b # letters in a or b but not both
frozenset 冻结的set:
frozenset
类型是不可变并且为 hashable — 其内容在被创建后不能再改变;因此它可以被用作字典的键或其他集合的元素。
fst = frozenset("abc")
字典 dict
字典比集合更常用,现实中很多东西都可以用字典表示,比如“通讯录”、“日志记录”。
字典可以理解为键值对的集合,如{‘鸽子’: 10001}。‘鸽子’: 10001 就是一个键值对。
'鸽子’是键,10001是对应的值。
我们通过键查找值。 因此键必须是不可变类型,如字符串或数字,包含不可变对象的元组。列表不可以作为键,因为列表可用append()等方法修改。键也必须是唯一的。
字典的创建:
常用的方法:
- 使用花括号内以逗号分隔
键: 值
对的方式:{'jack': 4098, 'sjoerd': 4127}
- 使用字典推导式:
{}
,{x: x ** 2 for x in range(10)}
- 使用类型构造器:
dict()
,dict([('foo', 100), ('bar', 200)])
,dict(foo=100, bar=200)
补充:使用类型构造器dit()创建字典。
class dict(**kwargs) #字典 class dict(mapping, **kwargs) #从映射 class dict(iterable, **kwargs) #从可迭代对象,iterable中每个元素都是一对 #如:[('two', 2), ('one', 1), ('three',3)]
a = dict(one=1, two=2, three=3) #key=value b = {'one': 1, 'two': 2, 'three': 3} #直接构造 c = dict(zip(['one', 'two', 'three'], [1, 2, 3])) # 从映射 d = dict([('two', 2), ('one', 1), ('three', 3)]) #从iterable e = dict({'three': 3, 'one': 1, 'two': 2}) # 从另一个dict f = dict({'one': 1, 'three': 3}, two=2) # dict , key=value a == b == c == d == e == f #这些方式创建的字典都等价
字典常用方法:
最常用的方法是通过键存储读取值。
tel = {'jack': 4098, 'sape': 4139} # 初始化 tel['guido'] = 412 # 存储值 tel['jack'] # 访问值 del tel['sape'] #删除值
get
(key[, default]) 更稳健地读取值。
如果 key 存在于字典中则返回 key 的值则返回 key 的值,否则返回 default。 如果 default 未给出则默认为 None
,因而此方法绝不会引发 KeyError
。
tel.get('jkl',0000) #jkl不在字典中时返回默认值0000,不会引发KeyError
对字典执行 list(d)
操作,返回该字典中所有键的列表,按插入次序排列。
检查某个键是否在字典中,使用in
'guido' in tel 'jack' not in tel
遍历字典
在字典中循环时,用 items()
方法可同时取出键和对应的值:
knights = {'gallahad': 'the pure', 'robin': 'the brave'} for k, v in knights.items(): print(k, v)
更新字典
update
([other])
使用来自 other 的键/值对更新字典,覆盖原有的键。 返回 None
。
update()
接受另一个字典对象,或者一个包含键/值对(二元组形式)的可迭代对象。 如果给出了关键字参数,则会以其所指定的键/值对更新字典: d.update(red=1, blue=2)
。
Counter
collections有很多扩展的子类,可以去文档的collections里找。
collections — 容器数据类型 — Python 3.10.4 文档
这里介绍一下常用的Counter
,Counter
是字典的一个子类,可以方便的统计次数。
from collections import Counter cnt = Counter() words = ['red', 'blue', 'red', 'green', 'blue', 'blue'] for word in words: cnt[word] += 1 print(cnt) # Counter({'blue': 3, 'red': 2, 'green': 1}) # 更便捷的方法 cnt2 = Counter(words) print(cnt2)
Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0,而不是弹出一个 KeyError
:
print(cnt['dark']) # 0
most_common
([n])
返回一个列表,其中包含 n 个最常见的元素及出现次数,按常见程度由高到低排序。
如果 n 被省略或为 None
,most_common()
将返回计数器中的 所有 元素。
(计数值相等的元素按首次出现的顺序排序):
Counter('abracadabra').most_common(3)
c.total() # 所有元素的计数总和 c.clear() # reset all counts list(c) # list unique elements set(c) # convert to a set dict(c) # convert to a regular dictionary c.items() # convert to a list of (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n least common elements +c # remove zero and negative counts