4.dict(字典)
dict中文名为字典,是一种集合结构,因为他满足集合的三个性质,即无序性,确定性和互异性。
创建一个字典的语法是:
ZergLing = {"attack": 5, "spend": 4.13, "price": 50}
print(ZergLing["attack"]) # 5
# 错误做法
ZergLing = {"attack": 5, "spend": 4.13, "price": 50, 'attack': 6}
print(ZergLing['attack']) # 6
相比Tuple和list,dict的特点就比较多了
- 查找比较快
- 占用更多空间
- key不可重复,且不可变
- 数据不保证有序存fang
1.访问
dict的访问和Tuple与list类似,但是必须要用key作为索引
ZergLing = {"attack": 5, "spend": 4.13, "price": 50}
print(ZergLing["attack"])
# 因为dict是无序的,所以没有下标
# print(ZergLing[0]) x
为了避免访问不存在的key,这里有三种办法。
1.使用in
if 'attack' in ZergLing:
print(ZergLing["attack"])
2.使用get方法
print(ZergLing.get('attack'))
print(ZergLing.get('attacks'))
get方法可以节省一个if判断。他如果访问了一个存在的key,则会返回对应的Value反之返回None
3.使用defaultdict(了解) ‘ ?疑问见相册 ’
这种方法需要使用到一个import,它的作用是导入一个外部的库
defaultdict用法(了解) - 信安2102-郑明 (tt99.top)
from collections import defaultdict
ZergLing = defaultdict(int)
ZergLing['attack'] = 5
print(ZergLing['armor']) # 输出0
2.修改
ZergLing = {'attack': 5, 'speed': 3.5}
ZergLing['speed'] = 3.25 # 字典里有这个key,直接赋值就可以修改了
print(ZergLing) # 输出{'attack': 5, 'speed': 3.25}
3.添加
ZergLing = {'attack': 5, 'speed': 3.25}
ZergLing['price'] = 50 # 字典里没有这个key,就会自动创建一个新的key
print(ZergLing) # {'attack': 5, 'speed': 3.25, 'price': 50}
print(ZergLing.setdefault('targets', 'ground')) # 输出ground
print(ZergLing.setdefault('price', '88')) # 输出50
setdefault,是一个复合的get操作,他接收两个参数,分别是key和value。首先,他会尝试去访问这个key。如果存在,则返回它对应的值。如果不存在,则创建这个key,并将值设置为value。然后返回value。
4.删除
和之前list的删除类似,可以使用del来删除
del ZergLing['attack']
当然,除了del,dict提供了pop方法来删除元素,不过稍有区别,比如
ZergLing.pop('attack')
可以看到dict删除元素的时候,需要一个key作为参数。所以我们可以用popitem
ZergLing.popitem()
但是要注意的是,由于dict本身的无序性,这里popitem删除的是最后一个插入的元素。
5.遍历
由于dict由key和value构成,我们先看看如何单独获得key和value的集合。
ZergLing = {"attack": 5, "spend": 4.13, "price": 50}
print(ZergLing.keys())
print(ZergLing.values())
输出:
dict_keys(['attack', 'spend', 'price'])
dict_values([5, 4.13, 50])
这两个方法返回的值是特殊的对象而不是list,不能直接使用下标访问。比如
print(ZergLing.keys()[0]) # 错误
他们的作用是遍历,我们可以使用for循环来访问:
for key in ZergLing.keys():
print(key, end=' ')
# 输出
attack spend price
类似的,还有一个items方法。可以同时遍历key和value,和之前讲到的enumerate非常类似。
ZergLing = {"attack": 5, "spend": 4.13, "price": 50}
for key, value in ZergLing.items():
print(f'key = {key}, value = {value}')
输出
key = attack, value = 5
key = spend, value = 4.13
key = price, value = 50
这样就可以遍历整个dict了,不过有一点要注意的是,在遍历过程中可以修改,但是不能添加删除,修改已有的值是没有问题的。
ZergLing = {"attack": 5, "spend": 4.13, "price": 50}
mun = 5
for key, value in ZergLing.items():
print(f'key = {key}, value = {value}')
mun += 1
ZergLing['attack'] = mun
print(ZergLing)
输出
key = attack, value = 5
{'attack': 6, 'spend': 4.13, 'price': 50}
key = spend, value = 4.13
{'attack': 7, 'spend': 4.13, 'price': 50}
key = price, value = 50
{'attack': 8, 'spend': 4.13, 'price': 50}
如果添加了新的key,会报错
for key, value in ZergLing.items():
RuntimeError: dictionary changed size during iteration
6.嵌套
carrier = {
'cost': {
'mineral': 350,
'gas': 250,
'supply': 6,
'build_time': 86
},
'type': [
'air',
'massive',
'mechanical'
],
'sight': 12,
'attack': 0,
'armor': 2
} # 这是一艘航空母舰
访问嵌套的元素
if 'air' in carrier['type']:
print('这个单位需要对空火力才能被攻击。')
print(f'单位生产要{carrier["cost"]["mineral"]}晶矿{carrier["cost"]["gas"]}高能瓦斯')
输出:
这个单位需要对空火力才能被攻击
单位生产要350晶矿250高能瓦斯
注意这里只能用双引号,原因。。不懂