铁乐学Python_day05-字典dict

1、【字典dict】

Python内置了字典:dict的支持,dict全称dictionary,
在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。

字典和列表直观上不同的是,字典用的是方括弧'{}’括起来,列表用的是方括号’[]’。

例,假设要根据hero3人族兵种的级别查找对应的兵种,如果用list实现,需要两个list:
Lv = [‘Lv1’, ‘Lv2’, ‘lv3’]
hum_soldier = [‘枪兵’, ‘射手’, ‘狮鹫’]

给定一个级别,要查找对应的hum_soldier,就先要在Lv中找到对应的位置,
再从hum_soldier取出对应的兵种,list越长,耗时越长。
如果用dict实现,只需要一个“Lv”-“hum_soldier”的对照表,直接根据级别查找兵种,
无论这个表有多大,查找速度都不会变慢。(但是会占的内存比LIST多)

字典这种采用键值对的方式(key-value),储存大量关系性的数据,查询速度快。

字典的值:任意数据类型。只有值能对应上所有类型,它的键只可以对应上不可变类型的数据。
字典的键:属于不可变数据类型。且不能重复,唯一。
所以键可以是int,bool,str,tuple,但不能是列表。
如果你建立两个相同的键,后赋值那个会覆盖前面那个同名的键。

字典的顺序:
3.5之前,字典是无序的。
3.6开始,有优化,字典创建的时候,按照一定的顺序插入的数值,看起来变得更有序。

数据类型分类:
可变(不可哈希):list,dict,set(集合)—unhashable type
不可变(可哈希):int,bool,str,tuple —hashable type
对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
(对原值没有发生改变,只是形成一个新的)

按容器(可承载各种数据类型)类型分:
容器类:list,tuple,dict

list列表,查询速度从头遍历到尾
disc字典,二分查找(有一个哈希表,每一个键[唯一]对应一个哈希值。

# hash
hum_soldier = {'lv1':'枪兵', 'lv2':'射手', 'lv3':'狮鹫'}
print(hash('lv1'))  # 可查看键对应的哈希值

得出hash值:
1863379157542317326

2、对字典的操作;

【增】加键值的方法学习两种:

第一种:直接通过键修改值;

有则覆盖(改),无则添加。和列表的索引增加类似。

hum_soldier = {'lv1':'枪兵', 'lv2':'射手', 'lv3':'狮鹫'}
hum_soldier['lv4'] = '剑士'
print(hum_soldier)

可以看到无则添加成:
{'lv4': '剑士', 'lv2': '射手', 'lv1': '枪兵', 'lv3': '狮鹫'}

有则覆盖的例子,上面中lv1的键值对己有,我现在直接覆盖修改成兵种变成农民:
hum_soldier['lv1'] = '农民'
print(hum_soldier)

效果:{'lv2': '射手', 'lv4': '剑士', 'lv3': '狮鹫', 'lv1': '农民'}

所以如果不确定数据有没有,及数据不可以覆盖的情况下,建议用到接下来要说的第二种:

第二种:setdeafult(),无则添加,有则不变。对数据的保护更高,更严谨。

如果 key 在 字典中,返回对应的值。
如果不在字典中,则插入 key 及设置的默认值 default,并返回 default ,default 默认值为 None。

比如同样接上文的例子,使用setdeafult()方法添加一组原来没有的键值对:

hum_soldier.setdefault('lv5', '僧侣')
print(hum_soldier)

输出可看到有添加:
{'lv1': '农民', 'lv2': '射手', 'lv5': '僧侣', 'lv3': '狮鹫', 'lv4': '剑士'}

再添加原来便有的lv2键尝试:
hum_soldier.setdefault('lv2', '神射手')
print(hum_soldier)

输出看到没有变化,lv2键对应的值依然是射手:
{'lv3': '狮鹫', 'lv2': '射手', 'lv5': '僧侣', 'lv4': '剑士', 'lv1': '农民'}

注意:同样由于setdefault()的这个特性,最好只在数据没有添加也不影响或有检查反馈的场合下用。

hum_soldier.setdefault('lv6')
也可以单纯只加一个键,默认键值为None,None也是常常会预留的。
很多时候我们新建的一个字典,就是先建好键,值都是默认None,后面再或获取或填入的。
{'lv3': '狮鹫', 'lv1': '农民', 'lv4': '剑士', 'lv2': '射手', 'lv6': None, 'lv5': '僧侣'}

利用setdeafult()的返回值特性,我们还可以尝试进行这样的操作:

hum_soldier = {'lv1': '农民', 'lv2': '射手', 'lv6': None, 'lv3': '狮鹫', 'lv5': '僧侣', 'lv4': '剑士'}

print('人类的一级兵种是:%s' % hum_soldier.setdefault('lv1', None))
print('人族的七级兵种是:%s' % hum_soldier.setdefault('lv7', None))
print(hum_soldier)

显示:
人类的一级兵种是:农民
人族的七级兵种是:None
{'lv1': '农民', 'lv6': None, 'lv5': '僧侣', 'lv3': '狮鹫', 'lv2': '射手', 'lv7': None, 'lv4': '剑士'}

【删除】的方法我们来学习四种:

1)【pop(key[,default)】

字典 pop() 方法删除字典给定键 key 所对应的值,返回值为被删除的值。
key值必须给出。 否则,返回default值。

例:

hum_soldier = {'lv1': '农民', 'lv2': '射手', 'lv6': None, 'lv3': '狮鹫', 'lv5': '僧侣', 'lv4': '剑士'}
print(hum_soldier.pop('lv1'))
print(hum_soldier)

显示:
农民
{'lv6': None, 'lv4': '剑士', 'lv7': None, 'lv5': '僧侣', 'lv3': '狮鹫', 'lv2': '射手'}

hum_soldier.pop('lv8')  #删除的时候没有此键的时候会报错
报错
Traceback (most recent call last):
  File "E:/Python/day05/dict.py", line 26, in <module>
    print(hum_soldier.pop('lv8'))
KeyError: 'lv8'

hum_soldier.pop('lv9', None) #建议以这种写法,不报错而是返回你设定的值,一般是None来提醒自已没有此键。
返回
None 
2)【popitem(key[,default)】

字典 popitem() 方法随机返回并删除字典中的一对键和值(一般删除末尾对)。
如果字典已经为空,却调用了此方法,就报出KeyError异常。

3)【clear()】清空字典所有元素,变空字典

例:

hum_soldier = {'lv1': '农民', 'lv2': '射手', 'lv3': '狮鹫', 'lv5': '僧侣', 'lv4': '剑士'}
print("人族兵种-字典长度为:%s" % len(hum_soldier))
hum_soldier.clear()
print("人族兵种-字典长度现为:%s" % len(hum_soldier))

返回结果:
人族兵种-字典长度为:5
人族兵种-字典长度现为:0
4)【del】不详述,前面已有练习删除列表等。

del dict 删除字典
del dict[’key’] 删除对应键值,没有时会报异常,所以建议一般使用pop来删除。

【改】的方法我们来学习两种:

第一种:直接通过键来修改(赋值)
hum_soldier = {'lv5': '僧侣', 'lv1': '农民', 'lv3': '狮鹫', 'lv2': '射手', 'lv4': '剑士'}
hum_soldier['lv1'] = '戟兵'
print(hum_soldier)

显示:
{'lv5': '僧侣', 'lv1': '戟兵', 'lv3': '狮鹫', 'lv2': '射手', 'lv4': '剑士'}
第二种:update()方法

dict.update(dict2)
将dict2键/值对,更新(覆盖并添加)到dict
(会覆盖,有相同会覆盖,没有的添加,和同步更新有点像)

hum_soldier = {'lv1':'枪兵', 'lv2':'射手', 'lv3':'狮鹫'}
hum = {'lv4':'剑士', 'lv5':'僧侣', 'lv1':'农民'}
hum_soldier.update(hum)
print(hum_soldier)
print(hum)

显示:(结果是hum_soldier字典中的枪兵被覆盖,再增加了剑士和僧侣,而hum字典保持不变。)
{'lv5': '僧侣', 'lv4': '剑士', 'lv2': '射手', 'lv1': '农民', 'lv3': '狮鹫'} 
{'lv4': '剑士', 'lv5': '僧侣', 'lv1': '农民'}

【查】的方法我们来学习三种

1)dict[‘key’]只能通过键查值,查不到的报错
2)通过in也可以判断key是否存在:

Python 字典 in 操作符用于判断键是否存在于字典中,如果键在字典dict里返回true,否则返回false。
语法
in 操作符语法:
key in dict
参数
key — 要在字典中查找的键。
返回值
如果键在字典里返回true,否则返回false。

hum = {'lv4':'剑士', 'lv5':'僧侣', 'lv1':'农民'}
print('lv2' in hum)
print('lv4' in hum)

显示:
False
True

注意是键-key,而不要弄成了判断值了。

3)dict.get(‘key’)通过键得到对应的值,找不到键的默认返回None。

语法
get()方法语法:
dict.get(key, default=None)
参数
key — 字典中要查找的键。
default — 如果指定键的值不存在时,返回该默认值值。
返回值
返回指定键的值,如果值不在字典中返回默认值 None。

例:

hum = {'lv4':'剑士', 'lv5':'僧侣', 'lv1':'农民'}
print('人族4级兵种为:%s' % hum.get('lv4'))

显示:
人族4级兵种为:剑士

3、【其它方法】

dict.keys()

字典keys() 方法以列表返回一个字典所有的键。

把所有的键(不包括值)放到一个容器中,
本身没什么用,类似于列表(但没有索引),可以用于for循环迭代打印输出所有键等。
dict.keys() 循环打印出所有键时,等同直接dict;

(另外可用list转换成列表:list(dic.keys()))
特殊类型转换 dict 转化成 list,类似:

hum = {'lv4':'剑士', 'lv5':'僧侣', 'lv1':'农民'}
print(hum.keys())
hum_list = list(hum.keys())
print(hum_list)

显示结果:
dict_keys(['lv4', 'lv5', 'lv1'])
['lv4', 'lv5', 'lv1']

dict.values()

字典 values() 方法以列表返回字典中的所有值。

与keys相对,这次是把所有值放到一个列表中。与keys()用法可触类旁通,不再详述。

dict.items()

字典 items() 方法以列表返回可遍历的(键, 值) 元组数组。

这个就厉害了,返回的是成对的键/值,而且是遍历。

例:

hum = {'lv4':'剑士', 'lv5':'僧侣', 'lv1':'农民'}
print(hum.items())

显示结果:
dict_items([('lv4', '剑士'), ('lv5', '僧侣'), ('lv1', '农民')])

字典 fromkeys()方法

fromkeys()方法从序列键和值设置为value来创建一个新的字典。
dict.fromkeys(seq[, value]))

参数
seq — 这是将用于字典的键准备的值的列表。一般为可迭代的对像。
value — 这是可选的,如果提供的话则值将被设置为这个值。

例:

dic ={}
lv1_soldier = ['骷髅', '枪兵', '小鬼', '大耳怪', '半人马', '小精灵', '妖精']
dic = dic.fromkeys(lv1_soldier, 'lv1')
print(dic)

{'小鬼': 'lv1', '小精灵': 'lv1', '枪兵': 'lv1', '妖精': 'lv1', '半人马': 'lv1', '骷髅': 'lv1', '大耳怪': 'lv1'}

【分别赋值】

a,b = 2,3
a,b = (2,3)
a,b = [2,3] #前提,数量一一对应得上
输出的结果都是a=2 b=3

a = 4 , b = 5 只用一行代码赋值a和b的值互换?(面试题)
a,b = b,a

扩展,因为键和值也是成对的,所以很多情况下也可以用到分别(双双)赋值的这个技巧。
还可以加上for循环遍历技巧。

for k,v in dict.items()
这里的循环对应的k和v就是取字典里的键/值对。

【字典 dict.zip() 迭代分别赋值给键和值。】

两个列表合并成字典

例:

hum_soldier = ['枪兵', '射手', '狮鹫', '剑士', '僧侣', '骑士', '天使']
lv = ['lv' + str(i) for i in range(1,8)] #列表推导式直接做出lv1到lv7
print(lv)
dic = dict(zip(lv, hum_soldier)) #分别对应列表顺序赋值给字典
print(dic)

['lv1', 'lv2', 'lv3', 'lv4', 'lv5', 'lv6', 'lv7']
{'lv2': '射手', 'lv1': '枪兵', 'lv5': '僧侣', 'lv4': '剑士', 'lv7': '天使', 'lv3': '狮鹫', 'lv6': '骑士'}

使用zip函数还可以很方便反转键值(原本的值当键,原本的键变成值)
例如接上例继续操作反转:

dic = dict(zip(dic.values(), dic.keys()))
print(dic)
{'狮鹫': 'lv3', '射手': 'lv2', '枪兵': 'lv1', '僧侣': 'lv5', '骑士': 'lv6', '剑士': 'lv4', '天使': 'lv7'}

4、【字典的嵌套】

字典通过键找值,列表通过索引找值;
例:

dic = {"name_list":['张三','lisi','隔壁王叔叔'],
       'dic2':{'name':'太白','age':12},
       }

#1 ,给列表追加一个元素:'旺旺'
dic['name_list'].append('旺旺')
print(dic)

#,2,给列表lisi全部大写
print(dic['name_list'][1]) #在不知道自已找的位置对不对的时候可以print调试看一下
# dic['name_list'][1] = 'LIST' #最low的时候可以直接赋值
dic['name_list'][1] = dic['name_list'][1].upper()
#print(dic)

#3,给dic2 对应的字典添加一个键值对:hobby:girl.
dic['dic2']['hobby'] ='girl'
print(dic)

文:铁乐与猫
2018-3-22
end

发表评论

电子邮件地址不会被公开。 必填项已用*标注

3 + 4 =